Voorgecompileerde programma's

Samenvatting

Precompiles (Ed25519, Secp256k1, Secp256r1) verifiëren handtekeningen als native code, waarbij de sBPF VM wordt omzeild. Ze verwerken cryptografische operaties waar sBPF- uitvoering te traag zou zijn. Precompiles zijn niet aanroepbaar via CPI.

Voorgecompileerde programma's

Voorgecompileerde programma's omzeilen de sBPF virtual machine en draaien als native code binnen de validator. Ze verwerken cryptografische operaties waar sBPF-uitvoering te traag zou zijn.

Ed25519-handtekening verifiëren

Het ed25519-programma verifieert één of meer ed25519-handtekeningen binnen een enkele instructie.

ProgrammaProgramma-IDBeschrijvingInstructiesBron
Ed25519-programmaEd25519SigVerify111111111111111111111111111Verifieert ed25519-handtekeningen. Als een handtekening faalt, wordt een fout geretourneerd.InstructiesBron

De eerste u8 van de instructie bevat een telling van het aantal te controleren handtekeningen, gevolgd door een enkele byte padding. Daarna wordt de volgende struct éénmaal per handtekening geserialiseerd:

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-herstel verifiëren

Het secp256k1-programma verifieert secp256k1 public key recovery-operaties (ecrecover).

ProgrammaProgramma-IDBeschrijvingInstructiesBron
Secp256k1-programmaKeccakSecp256k11111111111111111111111111111Verifieert secp256k1 public key recovery-operaties (ecrecover).InstructiesBron

De eerste byte van de instructie bevat een telling van het aantal te controleren publieke sleutels. Daarna wordt de volgende struct éénmaal per publieke sleutel geserialiseerd:

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
}

Handtekening- en berichtgegevens kunnen verwijzen naar alle instruction data in de transactie. Door de speciale instructions sysvar op te geven, kunnen programma's ook gegevens uit de transactie zelf lezen.

Transactiekosten zijn gelijk aan het aantal te verifiëren handtekeningen vermenigvuldigd met de verificatiekosten per handtekening.

Verifieer secp256r1-handtekening

Het secp256r1-programma verifieert maximaal 8 secp256r1-handtekeningen per instructie.

ProgrammaProgramma-IDBeschrijvingInstructiesBron
Secp256r1-programmaSecp256r1SigVerify1111111111111111111111111Verifieert maximaal 8 secp256r1-handtekeningen. Neemt een handtekening, publieke sleutel en bericht. Geeft een fout als een verificatie mislukt.InstructiesBron

De eerste u8 van de instructie is een telling van te controleren handtekeningen, gevolgd door een enkele byte padding. Daarna wordt de volgende struct eenmaal per handtekening geserialiseerd:

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
}

Lage S-waarden worden afgedwongen voor alle handtekeningen om onbedoelde handtekeningveranderlijkheid te voorkomen.

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?

Inhoudsopgave

Pagina Bewerken

Beheerd door

© 2026 Solana Foundation.
Alle rechten voorbehouden.
Blijf Verbonden