Riepilogo
I precompilati (Ed25519, Secp256k1, Secp256r1) verificano le firme come codice nativo, bypassando la VM sBPF. Gestiscono operazioni crittografiche dove l'esecuzione sBPF sarebbe troppo lenta. I precompilati non sono richiamabili tramite CPI.
Programmi precompilati
I programmi precompilati bypassano la macchina virtuale sBPF ed eseguono come codice nativo all'interno del validator. Gestiscono operazioni crittografiche dove l'esecuzione sBPF sarebbe troppo lenta.
Verifica firma ed25519
Il programma ed25519 verifica una o più firme ed25519 all'interno di una singola istruzione.
| Programma | ID programma | Descrizione | Istruzioni | Sorgente |
|---|---|---|---|---|
| Programma Ed25519 | Ed25519SigVerify111111111111111111111111111 | Verifica le firme ed25519. Se una firma fallisce, viene restituito un errore. | Istruzioni | Sorgente |
Il primo u8 dell'istruzione contiene un conteggio del numero di firme da
verificare, seguito da un singolo byte di padding. Successivamente, la seguente
struct viene serializzata una volta per firma:
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}
Verifica recupero secp256k1
Il programma secp256k1 verifica le operazioni di recupero della chiave pubblica secp256k1 (ecrecover).
| Programma | ID programma | Descrizione | Istruzioni | Sorgente |
|---|---|---|---|---|
| Programma Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Verifica le operazioni di recupero della chiave pubblica secp256k1 (ecrecover). | Istruzioni | Sorgente |
Il primo byte dell'istruzione contiene un conteggio del numero di chiavi pubbliche da verificare. Successivamente, la seguente struct viene serializzata una volta per chiave pubblica:
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}
I dati della firma e del messaggio possono fare riferimento a qualsiasi dato di istruzione nella transazione. Specificando la sysvar delle istruzioni speciali, i programmi possono anche leggere i dati dalla transazione stessa.
Il costo della transazione è uguale al numero di firme da verificare moltiplicato per il costo di verifica per firma.
Verifica firma secp256r1
Il programma secp256r1 verifica fino a 8 firme secp256r1 per istruzione.
| Programma | ID programma | Descrizione | Istruzioni | Sorgente |
|---|---|---|---|---|
| Programma Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Verifica fino a 8 firme secp256r1. Accetta una firma, una chiave pubblica e un messaggio. Restituisce errore se qualcuna fallisce. | Istruzioni | Sorgente |
Il primo u8 dell'istruzione è un conteggio delle firme da verificare, seguito
da un singolo byte di padding. Successivamente, la seguente struct viene
serializzata una volta per firma:
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}
I valori S bassi sono applicati per tutte le firme per evitare la malleabilità accidentale della firma.
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?