Program terkompilasi

Ringkasan

Precompile (Ed25519, Secp256k1, Secp256r1) memverifikasi tanda tangan sebagai kode native, melewati sBPF VM. Mereka menangani operasi kriptografi di mana eksekusi sBPF akan terlalu lambat. Precompile tidak dapat dipanggil melalui CPI.

Program terkompilasi

Program terkompilasi melewati mesin virtual sBPF dan berjalan sebagai kode native di dalam validator. Mereka menangani operasi kriptografi di mana eksekusi sBPF akan terlalu lambat.

Verifikasi tanda tangan ed25519

Program ed25519 memverifikasi satu atau lebih tanda tangan ed25519 dalam satu instruksi.

ProgramID programDeskripsiInstruksiSumber
Program Ed25519Ed25519SigVerify111111111111111111111111111Memverifikasi tanda tangan ed25519. Jika ada tanda tangan yang gagal, error akan dikembalikan.InstruksiSumber

u8 pertama instruksi berisi jumlah tanda tangan yang akan diperiksa, diikuti oleh satu byte padding. Setelah itu, struct berikut diserialisasi sekali per tanda tangan:

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
}

Verifikasi pemulihan secp256k1

Program secp256k1 memverifikasi operasi pemulihan kunci publik secp256k1 (ecrecover).

ProgramID programDeskripsiInstruksiSumber
Program Secp256k1KeccakSecp256k11111111111111111111111111111Memverifikasi operasi pemulihan kunci publik secp256k1 (ecrecover).InstruksiSumber

Byte pertama instruksi berisi jumlah kunci publik yang akan diperiksa. Setelah itu, struct berikut diserialisasi sekali per kunci publik:

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
}

Tanda tangan dan data pesan dapat mereferensikan instruction data apa pun dalam transaksi. Dengan menentukan sysvar instruksi khusus, program juga dapat membaca data dari transaksi itu sendiri.

Biaya transaksi sama dengan jumlah tanda tangan yang akan diverifikasi dikalikan dengan biaya verifikasi per tanda tangan.

Verifikasi tanda tangan secp256r1

Program secp256r1 memverifikasi hingga 8 tanda tangan secp256r1 per instruksi.

ProgramProgram IDDeskripsiInstruksiSumber
Program Secp256r1Secp256r1SigVerify1111111111111111111111111Memverifikasi hingga 8 tanda tangan secp256r1. Menerima tanda tangan, kunci publik, dan pesan. Mengembalikan error jika ada yang gagal.InstruksiSumber

u8 pertama instruksi adalah jumlah tanda tangan yang akan diperiksa, diikuti oleh satu byte padding. Setelah itu, struct berikut diserialisasi sekali per tanda tangan:

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
}

Nilai S rendah diberlakukan untuk semua tanda tangan guna menghindari kemungkinan malleabilitas tanda tangan.

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?

Daftar Isi

Edit Halaman

Dikelola oleh

© 2026 Yayasan Solana.
Semua hak dilindungi.
Terhubung