Önceden derlenmiş programlar

Özet

Önceden derlenmiş programlar (Ed25519, Secp256k1, Secp256r1) imzaları yerel kod olarak doğrular ve sBPF VM'yi atlar. sBPF yürütmesinin çok yavaş olacağı kriptografik işlemleri gerçekleştirir. Önceden derlenmiş programlar CPI aracılığıyla çağrılamaz.

Önceden derlenmiş programlar

Önceden derlenmiş programlar sBPF sanal makinesini atlayarak validator içinde yerel kod olarak çalışır. sBPF yürütmesinin çok yavaş olacağı kriptografik işlemleri gerçekleştirir.

Ed25519 imzasını doğrula

Ed25519 programı, tek bir talimat içinde bir veya daha fazla ed25519 imzasını doğrular.

ProgramProgram IDAçıklamaTalimatlarKaynak
Ed25519 programıEd25519SigVerify111111111111111111111111111Ed25519 imzalarını doğrular. Herhangi bir imza başarısız olursa hata döndürülür.TalimatlarKaynak

Talimatın ilk u8 kısmı kontrol edilecek imza sayısını ve ardından tek baytlık bir dolgu içerir. Bundan sonra, aşağıdaki yapı her imza için bir kez serileştirilir:

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 kurtarmayı doğrula

Secp256k1 programı, secp256k1 genel anahtar kurtarma işlemlerini (ecrecover) doğrular.

ProgramProgram IDAçıklamaTalimatlarKaynak
Secp256k1 programıKeccakSecp256k11111111111111111111111111111Secp256k1 genel anahtar kurtarma işlemlerini (ecrecover) doğrular.TalimatlarKaynak

Talimatın ilk baytı kontrol edilecek genel anahtar sayısını içerir. Bundan sonra, aşağıdaki yapı her genel anahtar için bir kez serileştirilir:

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
}

İmza ve mesaj verileri, işlemdeki herhangi bir instruction data'ya referans verebilir. Özel instructions sysvar'ı belirterek, programlar işlemin kendisinden de veri okuyabilir.

İşlem maliyeti, doğrulanacak imza sayısının imza başına doğrulama maliyetiyle çarpımına eşittir.

Secp256r1 imzasını doğrula

Secp256r1 programı, instruction başına 8 adede kadar secp256r1 imzasını doğrular.

ProgramProgram IDAçıklamaInstructionsKaynak
Secp256r1 ProgramSecp256r1SigVerify11111111111111111111111118 adede kadar secp256r1 imzasını doğrular. İmza, açık anahtar ve mesaj alır. Herhangi biri başarısız olursa hata döndürür.InstructionsKaynak

Instruction'ın ilk u8 değeri, kontrol edilecek imza sayısıdır ve ardından tek bir dolgu baytı gelir. Bundan sonra, aşağıdaki yapı her imza için bir kez serileştirilir:

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
}

Kazara imza değiştirilebilirliğini önlemek için tüm imzalar için düşük S değerleri zorunlu tutulur.

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?

İçindekiler

Sayfayı Düzenle

Yönetici

© 2026 Solana Vakfı.
Tüm hakları saklıdır.
Bağlanın