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.
| Program | ID program | Deskripsi | Instruksi | Sumber |
|---|---|---|---|---|
| Program Ed25519 | Ed25519SigVerify111111111111111111111111111 | Memverifikasi tanda tangan ed25519. Jika ada tanda tangan yang gagal, error akan dikembalikan. | Instruksi | Sumber |
u8 pertama instruksi berisi jumlah tanda tangan yang akan diperiksa, diikuti
oleh satu byte padding. Setelah itu, struct berikut diserialisasi sekali per
tanda tangan:
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}
Verifikasi pemulihan secp256k1
Program secp256k1 memverifikasi operasi pemulihan kunci publik secp256k1 (ecrecover).
| Program | ID program | Deskripsi | Instruksi | Sumber |
|---|---|---|---|---|
| Program Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Memverifikasi operasi pemulihan kunci publik secp256k1 (ecrecover). | Instruksi | Sumber |
Byte pertama instruksi berisi jumlah kunci publik yang akan diperiksa. Setelah itu, struct berikut diserialisasi sekali per kunci publik:
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}
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.
| Program | Program ID | Deskripsi | Instruksi | Sumber |
|---|---|---|---|---|
| Program Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Memverifikasi hingga 8 tanda tangan secp256r1. Menerima tanda tangan, kunci publik, dan pesan. Mengembalikan error jika ada yang gagal. | Instruksi | Sumber |
u8 pertama instruksi adalah jumlah tanda tangan yang akan diperiksa, diikuti
oleh satu byte padding. Setelah itu, struct berikut diserialisasi sekali per
tanda tangan:
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}
Nilai S rendah diberlakukan untuk semua tanda tangan guna menghindari kemungkinan malleabilitas tanda tangan.
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?