البرامج المترجمة مسبقًا

ملخص

البرامج المترجمة مسبقًا (Ed25519، Secp256k1، Secp256r1) تتحقق من التوقيعات كشفرة أصلية، متجاوزة جهاز sBPF الافتراضي. تتعامل مع العمليات التشفيرية حيث يكون تنفيذ sBPF بطيئًا جدًا. لا يمكن استدعاء البرامج المترجمة مسبقًا عبر CPI.

البرامج المترجمة مسبقًا

تتجاوز البرامج المترجمة مسبقًا الجهاز الافتراضي sBPF وتعمل كشفرة أصلية داخل المدقق. تتعامل مع العمليات التشفيرية حيث يكون تنفيذ sBPF بطيئًا جدًا.

التحقق من توقيع ed25519

يتحقق برنامج ed25519 من توقيع واحد أو أكثر من توقيعات ed25519 ضمن تعليمة واحدة.

البرنامجمعرف البرنامجالوصفالتعليماتالمصدر
برنامج Ed25519Ed25519SigVerify111111111111111111111111111يتحقق من توقيعات ed25519. إذا فشل أي توقيع، يتم إرجاع خطأ.التعليماتالمصدر

يحتوي u8 الأول للتعليمة على عدد التوقيعات المراد التحقق منها، متبوعًا ببايت واحد من الحشو. بعد ذلك، يتم تسلسل البنية التالية مرة واحدة لكل توقيع:

Ed25519SignatureOffsets
struct Ed25519SignatureOffsets {
signature_offset: u16, // offset to ed25519 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to public key of 32 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}
Signature verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
instruction_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).

البرنامجمعرف البرنامجالوصفالتعليماتالمصدر
برنامج Secp256k1KeccakSecp256k11111111111111111111111111111يتحقق من عمليات استرداد المفتاح العام secp256k1 (ecrecover).التعليماتالمصدر

يحتوي البايت الأول للتعليمة على عدد المفاتيح العامة المراد التحقق منها. بعد ذلك، يتم تسلسل البنية التالية مرة واحدة لكل مفتاح عام:

SecpSignatureOffsets
struct SecpSignatureOffsets {
signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytes
signature_instruction_index: u8, // instruction index to find signature
eth_address_offset: u16, // offset to ethereum_address of 20 bytes
eth_address_instruction_index: u8, // instruction index to find ethereum address
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u8, // instruction index to find message data
}
Recovery verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
signature = 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 لكل تعليمة.

البرنامجمعرف البرنامجالوصفالتعليماتالمصدر
برنامج Secp256r1Secp256r1SigVerify1111111111111111111111111يتحقق من ما يصل إلى 8 توقيعات secp256r1. يأخذ توقيعًا ومفتاحًا عامًا ورسالة. يُرجع خطأ في حالة فشل أي منها.التعليماتالمصدر

أول u8 في التعليمة هو عدد التوقيعات المراد التحقق منها، متبوعًا ببايت واحد للحشو. بعد ذلك، يتم تسلسل البنية التالية مرة واحدة لكل توقيع:

Secp256r1SignatureOffsets
struct Secp256r1SignatureOffsets {
signature_offset: u16, // offset to compact secp256r1 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to compressed public key of 33 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}

يتم فرض قيم S منخفضة لجميع التوقيعات لتجنب قابلية التوقيع للتلاعب العرضي.

Signature verification pseudocode
process_instruction() {
if data.len() < SIGNATURE_OFFSETS_START {
return Error
}
num_signatures = data[0] as usize
if num_signatures == 0 || num_signatures > 8 {
return Error
}
expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START
if 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?

جدول المحتويات

تعديل الصفحة

تدار بواسطة

© 2026 مؤسسة سولانا.
جميع الحقوق محفوظة.
تواصل معنا