Ö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.
| Program | Program ID | Açıklama | Talimatlar | Kaynak |
|---|---|---|---|---|
| Ed25519 programı | Ed25519SigVerify111111111111111111111111111 | Ed25519 imzalarını doğrular. Herhangi bir imza başarısız olursa hata döndürülür. | Talimatlar | Kaynak |
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:
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 kurtarmayı doğrula
Secp256k1 programı, secp256k1 genel anahtar kurtarma işlemlerini (ecrecover) doğrular.
| Program | Program ID | Açıklama | Talimatlar | Kaynak |
|---|---|---|---|---|
| Secp256k1 programı | KeccakSecp256k11111111111111111111111111111 | Secp256k1 genel anahtar kurtarma işlemlerini (ecrecover) doğrular. | Talimatlar | Kaynak |
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:
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}
İ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.
| Program | Program ID | Açıklama | Instructions | Kaynak |
|---|---|---|---|---|
| Secp256r1 Program | Secp256r1SigVerify1111111111111111111111111 | 8 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. | Instructions | Kaynak |
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:
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}
Kazara imza değiştirilebilirliğini önlemek için tüm imzalar için düşük S değerleri zorunlu tutulur.
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?