كيف يمكن أن يقدم zk-ASM إنترنتًا آمنًا وخاليًا من الثقة

تحليل بحثي أصلي من Web3.com Ventures

0xFishylosopher

ملاحظة: هذه المقالة قطعة تقنية كثيفة إلى حد ما، وتفترض معرفة أساسية بالمفاهيم المتعلقة بالبرهان الصفري و/أو التجميع الصفري. يمكن العثور على مقدمة أكثر عمومية لهذه المبادئ هنا.

مقدمة

البرهان الصفري، وبالتحديد zk-SNARKs (حجج المعرفة غير التفاعلية الموجزة) هي ربما واحدة من أهم التقنيات في حدود الويب 3. بينما ذهبت معظم وسائل الإعلام وتركيز الاستثمار في هذا المجال الفرعي نحو zk-Rollups، وهي حلول للتوسع توفر مقاييس من القابلية للتوسع لكتل L1 مثل Ethereum، فإن هذا ليس التطبيق الوحيد لـ zk-SNARKs. في هذه المقالة، سأقوم بتحليل مفهوم رمز التجميع الصفري (أو zkASM) بعمق، مع تقييم حالات استخدامه في كل من zk-Rollups وما بعدها، واستكشاف إمكانياته النظرية في إعادة اختراع الإنترنت كما نعرفه.

المبادئ التقنية

zk-ASM، كما يوحي الاسم، يحتوي على جزأين تقنيين رئيسيين: ZK وASM. يشير جزء ZK إلى zk-SNARKs، أو Succinct Non-Interactive Arguments of Knowledge، بينما يشير جزء ASM إلى كود Assembly. لفهم إمكانات zk-ASM، يجب علينا أولًا فهم الأسس النظرية لهذين المفهومين الغامضين ظاهريًا.

zk-SNARKs

تُعد zk-SNARKs جوهرة التاج في zk-Proofs: إنها برهان مُوجز يثبت أن عبارة ما صحيحة دون أن يكشف البرهان شيئًا عن البيانات التي تم إثباتها. على سبيل المثال، لنفترض أن شخصًا يؤكد العبارة “أعرف m بحيث C(m) = 0”، حيث تكون m رسالة طويلة بحجم جيجابايت وC دالة. ستكون zk-SNARK برهانًا قصيرًا جدًا (عند 1GB) يمكن التحقق منه بسرعة، ولا يُفصح عن أي شيء حول m (بخلاف المعلومات المتاحة علنًا) [1].

فما هو هذا “C(m)”؟ وكيف يكون مفيدًا؟ هذه الدالة هي في الحقيقة دائرة حسابية، أو تمثيل على شكل Directed Acyclic Graph (DAG) لدالة محددة نريد تنفيذها، كما يوضح الرسم [2]. إن “m” هي في جوهرها بيانات الإدخال إلى الدائرة، و”العُقد” المحددة داخل الدائرة هي بوابات منطقية فردية أو عمليات حسابية. على سبيل المثال، قد تحتوي عقدة “+” على “2” و“3” كمدخلات، ثم تُنتج “5” للمعامل التالي. وهكذا، يمكن ترميز أي عملية حسابية أو منطقية تعسفية في “دائرة حسابية”.

بمجرد أن نحصل على هذه الدائرة الحسابية كتَمثيل للكود الذي نريد تشغيل zk-SNARK عليه، يمكننا البدء ببناء zk-SNARK هذا. جوهريًا، يمكن إجراء zk-SNARK لأن هناك “نظرية الأسس الأساسية” (fundamental theorem of algebra)، التي تنص على أن كثير الحدود من الدرجة “d” يمتلك جذورًا بحد أقصى “d”. الحيلة الرياضية تنطوي على خطوتين: (1) تحويل الدالة “f(m)” التي نريد إثباتها إلى كثير حدود (والالتزام بذلك)، و(2) استخدام “نظرية الأسس الأساسية” للتفاعل مع كثير الحدود وتقديم برهان مُوجز. وبالمصطلحات التقنية، يُسمّى الجزء الأول “Polynomial Commitment Scheme” (PCS)، ويُسمّى الجزء الثاني “Polynomial Interactive Oracle Proof” (PIOP) [4].

على الرغم من أن التطبيقات المحددة لـ PCS وPIOP خارج نطاق هذه المقالة، فقد استخلصنا حتى الآن مخططًا تقريبيًا للخطوات الأساسية في zk-SNARK:

  1. لدينا دالة من اختيارنا (دالة كود، معادلة رياضية، إلخ) نريد تشغيل zk-SNARK عليها

  2. نُشفّر هذه الدالة كدائرة حسابية C(m)

  3. نُشغّل PCS للحصول على تمثيل متعدد الحدود لهذه الدائرة الحسابية

  4. نُشغّل PIOP للحصول على برهان مُوجز يكون حجمه لوغاريتميًا بالنسبة إلى الحجم الأصلي لـ “m”

وهكذا، نكون قد حصلنا على zk-SNARK مخصص يمكنه إثبات أن شخصًا ما يعرف رسالة معينة دون كشف ماهية تلك الرسالة.

كود التجميع (Assembly Code)

الجزء الثاني من لغز zk-ASM هو فكرة Assembly Code. كود التجميع هو فئة من اللغات التي تحتوي على تعليمات منخفضة جدًا (منخفضة المستوى) وسهلة على الآلة للقراءة، لكنها صعبة نسبيًا على الإنسان لفك ترميزها. على عكس اللغات عالية المستوى، مثل Python أو Java أو حتى C، تحتوي لغات Assembly على دوال بدائية جدًا، مثل move وcompare وadd وjump ضمن سلسلة من سجلات البيانات على المعالج ومواقع ذاكرة مُضمنة مسبقًا. على سبيل المثال، فإن كود Python لطباعة الأرقام من 1 إلى 9 على الشاشة هو 123456789:

سهل الفهم، أليس كذلك؟ والآن إليك نسخة x86 من كود Assembly الخاصة بذلك [5]:

أكثر تعقيدًا بكثير، خصوصًا لعملية بسيطة مثل هذه. إذن لماذا نستخدم لغة Assembly أصلًا؟ كما ذُكر أعلاه، على الرغم من أن هذه التعليمات قد لا تكون سهلة على الإنسان لقراءتها، إلا أنها سهلة جدًا لـ “تجميعها” في byte-code مثل 110011001 بحيث تقرأه الآلة وتنفّذه (ويُسمى ذلك assembler) [6]. بالمقارنة، فإن لغات المستوى الأعلى مثل Python وJava تكون أكثر سهولة للإنسان في القراءة، لكن البرامج المكتوبة بهذه اللغات لا يمكن تنفيذها مباشرة من قِبل المعالج. بدلًا من ذلك، نحتاج الاعتماد على “مُجمّع” (compiler) يقوم بهضم كود Python أو Java الذي نكتبه ويُخرج تفريغًا لكود Assembly مثل المثال أعلاه ليتم تجميعه وتنفيذه بواسطة الآلة. يمكننا توقع أن يعمل نفس جزء كود Python أو Java بسلاسة عبر معالجات وأنظمة تشغيل مختلفة لأن المُجمّع يتولى الأعمال الثقيلة: تجميع كود المصدر لديك إلى لغة Assembly خاصة بذلك المعالج أو نظام التشغيل.

بما أن جميع اللغات تُترجم إلى كود Assembly (الذي تتم ترجمته بدوره إلى ثنائي تنفيذي قابل للتنفيذ)، فإن Assembly تشبه عمليًا “أم جميع اللغات”. والآن لنفترض أننا قادرون على تحويل جميع المعاملات (operands) في لغة Assembly (مثل x86 أو RISC-V) إلى تمثيل دائرة حسابية، بحيث نتمكن من تقديم إثباتات zk-SNARK لجميع المعاملات في لغة Assembly هذه. هذا يعني أنه من الناحية النظرية يمكننا تقديم zk-SNARK لأي برنامج مكتوب بلغة عالية المستوى تعسفية (مثل Python أو Java) يتم تجميعه إلى لغة Assembly هذه. ولهذا السبب نحتاج إلى الاهتمام بالتفكير في zk-ASMs.

التطبيقات العملية

تجميعات zk-EVM: Polygon zk-ASM

تُعد إحدى أهم تطبيقات zk-ASM هي إنشاء تجميعات zk-Rollups متوافقة مع آلة افتراضية لجافا سكريبت (Ethereum Virtual Machine)، أي zk-EVMs. يُعد zk-EVM مهمًا للغاية لتوسّع البلوكشين، لأنه يسمح للمبرمجين بالنشر على سلسلة L2 قائمة على zk-Rollup دون تعديل كبير (إن وُجد) على كودهم [7]. في هذا المجال، تُعد حالة Polygon الخاصة بـ zk-EVM مثالًا يُحتذى به تُظهر كيف يمكن استخدام zk-ASM لتحقيق هذا الهدف.

عندما يطوّر المبرمجون على بلوكشين Ethereum L1، فإنهم عادة يكتبون بلغة Solidity، وهي لغة عالية المستوى شبيهة بـ C. يتم تجميع كود Solidity هذا إلى سلسلة من أوامر EVM (EVM Opcodes)، مثل ADD وSLOAD وEQ، قبل تنفيذها على بلوكشين L1 [8]. وبشكل افتراضي، فإن هذه العملية بالطبع لا تُنشئ أي نوع من zk-Proof. الحيلة لدى Polygon هي إنشاء طريقة لتفسير كل أوامر EVM إلى zk-ASM مخصص مكتوب يدويًا، وهو ملائم جدًا لـ zk-SNARK. ثم سينفّذ zk-EVM الخاص بهم zk-ASM، وفي الوقت نفسه ينشئ دائرة zk-SNARK الخاصة بـ ASM من أجل إنتاج برهان zk-SNARK [9]. على سبيل المثال، سيتم ترجمة أمر ADD في EVM إلى zk-ASM في Polygon على النحو التالي [10]:

بما أن الخدعة في Polygon zk-EVM تحدث على مستوى التجميع (Assembly)، فهي بعيدة بمقدار مستويين عن الكود الذي يتعامل معه أغلب مبرمجي Ethereum: مستوى “Solidity”. ولهذا السبب يستطيع معظم المطورين نقل كود EVM الذي بنوه من أجل الشبكة الرئيسية في Ethereum مباشرةً إلى Polygon zk-EVM. علاوة على ذلك، وبما أن Polygon “تحافظ” على سلسلة التقنيات الخاصة بـ Ethereum حتى مستوى الأوبكود، فسيظل من الممكن استخدام البنية التحتية للتصحيح التي تعتمد على تحليل الأوبكودات المجمعة كما هي وبشكل كامل. وهذا يختلف عن بعض تصميمات zk-EVM الأخرى، مثل zk-Sync، التي لا تُوفّر zk-Proofs على مستوى الأوبكود. لذا، حتى بينما تُنشئ Polygon وتُثبت لغة Assembly الخاصة بها، يكتب Vitalik أنه “يمكنها ما زال التحقق من كود EVM، لكنها تستخدم منطقًا داخليًا مختلفًا للقيام بذلك” [11].

ما وراء الـ Rollups: zk-WASM

لا تُعد zk-EVMs بأي حال من الأحوال التطبيق الوحيد ل zk-ASMs. تذكّر مقولتنا السابقة بأن لغات Assembly هي عمليًا “أم جميع اللغات”، وأن إنشاء zk-ASM سيُطلق zk-Proofs للبرامج العامة المكتوبة بأي لغة تتوافق مع تلك لغة Assembly. Web Assembly أو WASM هي إحدى أهم لغات Assembly الناشئة. نُشر WASM لأول مرة في 2018، والهدف منه هو إنشاء لغة Assembly تزيد من سرعة تنفيذ تطبيقات الويب، وتوفّر تكاملًا تنفيذيًا مع JavaScript، وهي اللغة الأساسية المستخدمة في البرمجة على الويب [12].

بشكل أساسي، ومع تطور الويب عبر السنوات، أدّى ازدياد حجم تطبيقات الويب وتعقيدها إلى أن يكون من الشائع أن يكون تجميع كل ما كُتب في JavaScript بطيئًا جدًا على المتصفحات، وأن يحتاج الأمر إلى الاعتماد على دورات معقّدة من “التجميع-التحسين-إعادة التحميل” [12]. من ناحية أخرى، يزيل WebAssembly الحاجة إلى الاعتماد على محركات تنفيذ متصفح معقّدة عبر توفير لغة Assembly محمولة ووحدوية وسهلة التنفيذ. بالإضافة إلى ذلك، وباعتبار WASM لغة Assembly، يتيح للمبرمجين كتابة مقاطع كود مباشرة في C أو C++ أو Rust أو Java أو Ruby تُنفَّذ أصليًا داخل المتصفح. وبذلك أصبحت WASM تقنية مُفضلة لـ “توفير وظائف موزعة دون خادم” [13].

فلماذا وكيف تدخل zk-SNARKs في الصورة؟ تتميز WASM بأنها تقنية تعمل على جهة العميل (client-side)، وقادرة على التفاعل مباشرةً مع مدخلات المستخدم والبيانات. وغالبًا ما يتضمن ذلك بيانات حساسة مثل كلمات المرور والمعلومات الشخصية، لذلك نحتاج إلى تقنية (1) تضمن أن البرنامج ينفّذ بشكل صحيح، و(2) ألا تتسرّب معلوماتنا الحساسة. كما هو موضح أعلاه، يُعد zk-SNARK حلًا مثاليًا لمعالجة المشكلتين معًا، وبالتالي فهو عنصر مهم في تأمين WASM [14].

على الرغم من أن العمل على تطوير zk-WASM ما زال في مراحله المبكرة، فقد ظهرت مؤخرًا بعض المشاريع التي أصدرت دوائر تجريبية لـ zk-SNARKs مخصصة لـ WebAssembly. على سبيل المثال، يُقدّم مُحاكي Delphinus Lab “ZAWA” الخاص بـ zk-SNARK طريقة لترميز مدخلات دوال WASM ودلالاتها إلى دائرة حسابية، ما يسمح لها بإجراء إثباتات zk-SNARK [13]. ومع مرور الوقت، ستجري بلا شك تحسينات مستمرة على دوائر zk-WASM، ما سيسمح للبرامج المكتوبة بلغات عامة (مثل C وC++ وRust وRuby) باعتماد نموذج zk-Proofs.

الخلاصة

طوال هذا المقال، استكشفنا الأسس النظرية لـ zk-ASM، كما نظرنا في حالتين دراسيتين واضحتين لـ zk-ASM: استخدام Polygon لـ zk-ASM لإنشاء zk-EVM على مستوى الأوبكود، وكذلك تطبيق zk-SNARKs على WebAssembly لإنشاء zk-WASM. في النهاية، تكمن الوعود من zk-ASM في جمع قابلية التوافق وقابلية التوسع لدى Web 2 مع اللا-ثقة والأمان لدى Web 3.

من جهة، تحاول البلوكشينات باستمرار التوسع بما يتجاوز عنق الزجاجة الحالي في الإنتاجية وربما دعم التنفيذ؛ ومن جهة أخرى، أصبحت طرق Web 2 مُستهدفة بشكل متزايد بسبب عدم كفاية حماية بيانات المستخدم والخصوصية. وبما أن المبرمجين يستطيعون توظيف مبادئ تصميم Web 3 داخل كود Web 2، وإدخال لغات Web 2 والكود الخاص بها إلى البلوكشين، فقد تمثل zk-ASMs العامة نقطة التقاء في عالم Web 2 وWeb 3 [15]. وبهذا المعنى، قد تسمح لنا zk-ASM بإعادة تصور إنترنت أكثر أمانًا وأكثر لا-ثقة.

🐦 @0xfishylosopher

📅 17 ديسمبر 2022

تنبيه: المعلومات المعروضة أعلاه هي لأغراض تعليمية بحتة ولا تشكل نصيحة مالية، وهي تعبر عن آراء المؤلف وحده. Delphinus Lab هي شركة ضمن محفظة Web3.com Ventures.

المراجع

[1] https://z.cash/technology/zksnarks/

[2] https://cs251.stanford.edu/lectures/lecture14.pdf

[3] https://www.britannica.com/science/fundamental-theorem-of-algebra

[4] Building efficient SNARKs: https://cs251.stanford.edu/lectures/lecture15.pdf

[5] مثال من: https://www.tutorialspoint.com/assembly_programming/assembly_loops.htm

[6] https://en.wikipedia.org/wiki/Assembly_language

[7] https://www.alchemy.com/overviews/zkevm

[8] لقائمة الأوبكودات: https://ethereum.org/en/developers/docs/evm/opcodes/

[9] https://wiki.polygon.technology/docs/zkEVM/zkASM/introduction

[10] https://wiki.polygon.technology/docs/zkEVM/zkASM/some-examples

[11] https://vitalik.ca/general/2022/08/04/zkevm.html

[12] https://blog.developer.adobe.com/understanding-webassembly-wasm-d5b592208ecc

[13] https://jhc.sjtu.edu.cn/~hongfeifu/manuscriptb.pdf

[14] https://hyperoracle.medium.com/zkwasm-the-next-chapter-of-zk-and-zkvm-471038b1fba6

[15] https://delphinuslab.com/zk-wasm/