ملخص
البرامج المترجمة مسبقًا (Ed25519، Secp256k1، Secp256r1) تتحقق من التوقيعات كشفرة أصلية، متجاوزة جهاز sBPF الافتراضي. تتعامل مع العمليات التشفيرية حيث يكون تنفيذ sBPF بطيئًا جدًا. لا يمكن استدعاء البرامج المترجمة مسبقًا عبر CPI.
البرامج المترجمة مسبقًا
تتجاوز البرامج المترجمة مسبقًا الجهاز الافتراضي sBPF وتعمل كشفرة أصلية داخل المدقق. تتعامل مع العمليات التشفيرية حيث يكون تنفيذ sBPF بطيئًا جدًا.
التحقق من توقيع ed25519
يتحقق برنامج ed25519 من توقيع واحد أو أكثر من توقيعات ed25519 ضمن تعليمة واحدة.
| البرنامج | معرف البرنامج | الوصف | التعليمات | المصدر |
|---|---|---|---|---|
| برنامج Ed25519 | Ed25519SigVerify111111111111111111111111111 | يتحقق من توقيعات ed25519. إذا فشل أي توقيع، يتم إرجاع خطأ. | التعليمات | المصدر |
يحتوي u8 الأول للتعليمة على عدد التوقيعات المراد التحقق منها، متبوعًا ببايت
واحد من الحشو. بعد ذلك، يتم تسلسل البنية التالية مرة واحدة لكل توقيع:
struct Ed25519SignatureOffsets {signature_offset: u16, // offset to ed25519 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to public key of 32 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionsinstruction_index = ed25519_signature_instruction_index != u16::MAX ? ed25519_signature_instruction_index : current_instruction;signature = instructions[instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]instruction_index = ed25519_pubkey_instruction_index != u16::MAX ? ed25519_pubkey_instruction_index : current_instruction;pubkey = instructions[instruction_index].data[ed25519_pubkey_offset..ed25519_pubkey_offset + 32]instruction_index = ed25519_message_instruction_index != u16::MAX ? ed25519_message_instruction_index : current_instruction;message = instructions[instruction_index].data[ed25519_message_data_offset..ed25519_message_data_offset + ed25519_message_data_size]if pubkey.verify(signature, message) != Success {return Error}}return Success}
التحقق من استرداد secp256k1
يتحقق برنامج secp256k1 من عمليات استرداد المفتاح العام secp256k1 (ecrecover).
| البرنامج | معرف البرنامج | الوصف | التعليمات | المصدر |
|---|---|---|---|---|
| برنامج Secp256k1 | KeccakSecp256k11111111111111111111111111111 | يتحقق من عمليات استرداد المفتاح العام secp256k1 (ecrecover). | التعليمات | المصدر |
يحتوي البايت الأول للتعليمة على عدد المفاتيح العامة المراد التحقق منها. بعد ذلك، يتم تسلسل البنية التالية مرة واحدة لكل مفتاح عام:
struct SecpSignatureOffsets {signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytessignature_instruction_index: u8, // instruction index to find signatureeth_address_offset: u16, // offset to ethereum_address of 20 byteseth_address_instruction_index: u8, // instruction index to find ethereum addressmessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u8, // instruction index to find message data}
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionssignature = instructions[signature_instruction_index].data[signature_offset..signature_offset + 64]recovery_id = instructions[signature_instruction_index].data[signature_offset + 64]ref_eth_pubkey = instructions[eth_address_instruction_index].data[eth_address_offset..eth_address_offset + 20]message_hash = keccak256(instructions[message_instruction_index].data[message_data_offset..message_data_offset + message_data_size])pubkey = ecrecover(signature, recovery_id, message_hash)eth_pubkey = keccak256(pubkey[1..])[12..]if eth_pubkey != ref_eth_pubkey {return Error}}return Success}
يمكن للتوقيع وبيانات الرسالة الإشارة إلى أي بيانات تعليمات في المعاملة. من خلال تحديد متغير النظام الخاص بالتعليمات، يمكن للبرامج أيضًا قراءة البيانات من المعاملة نفسها.
تكلفة المعاملة تساوي عدد التوقيعات المراد التحقق منها مضروبًا في تكلفة التحقق لكل توقيع.
التحقق من توقيع secp256r1
يتحقق برنامج secp256r1 من ما يصل إلى 8 توقيعات secp256r1 لكل تعليمة.
| البرنامج | معرف البرنامج | الوصف | التعليمات | المصدر |
|---|---|---|---|---|
| برنامج Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | يتحقق من ما يصل إلى 8 توقيعات secp256r1. يأخذ توقيعًا ومفتاحًا عامًا ورسالة. يُرجع خطأ في حالة فشل أي منها. | التعليمات | المصدر |
أول u8 في التعليمة هو عدد التوقيعات المراد التحقق منها، متبوعًا ببايت واحد
للحشو. بعد ذلك، يتم تسلسل البنية التالية مرة واحدة لكل توقيع:
struct Secp256r1SignatureOffsets {signature_offset: u16, // offset to compact secp256r1 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to compressed public key of 33 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
يتم فرض قيم S منخفضة لجميع التوقيعات لتجنب قابلية التوقيع للتلاعب العرضي.
process_instruction() {if data.len() < SIGNATURE_OFFSETS_START {return Error}num_signatures = data[0] as usizeif num_signatures == 0 || num_signatures > 8 {return Error}expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_STARTif data.len() < expected_data_size {return Error}for i in 0..num_signatures {offsets = parse_signature_offsets(data, i)signature = get_data_slice(data, instruction_datas, offsets.signature_instruction_index, offsets.signature_offset, SIGNATURE_SERIALIZED_SIZE)if s > half_curve_order {return Error}pubkey = get_data_slice(data, instruction_datas, offsets.public_key_instruction_index, offsets.public_key_offset, COMPRESSED_PUBKEY_SERIALIZED_SIZE)message = get_data_slice(data, instruction_datas, offsets.message_instruction_index, offsets.message_data_offset, offsets.message_data_size)if !verify_signature(signature, pubkey, message) {return Error}}return Success}
Is this page helpful?