Vorkompilierte Programme

Zusammenfassung

Precompiles (Ed25519, Secp256k1, Secp256r1) verifizieren Signaturen als nativer Code und umgehen dabei die sBPF-VM. Sie verarbeiten kryptografische Operationen, bei denen die sBPF- Ausführung zu langsam wäre. Precompiles können nicht über CPI aufgerufen werden.

Vorkompilierte Programme

Vorkompilierte Programme umgehen die virtuelle sBPF-Maschine und werden als nativer Code innerhalb der Validatoren ausgeführt. Sie verarbeiten kryptografische Operationen, bei denen die sBPF-Ausführung zu langsam wäre.

Ed25519-Signatur verifizieren

Das ed25519-Programm verifiziert eine oder mehrere ed25519-Signaturen innerhalb einer einzelnen Anweisung.

ProgrammProgramm-IDBeschreibungAnweisungenQuelle
Ed25519-ProgrammEd25519SigVerify111111111111111111111111111Verifiziert ed25519-Signaturen. Wenn eine Signatur fehlschlägt, wird ein Fehler zurückgegeben.AnweisungenQuelle

Das erste u8 der Anweisung enthält die Anzahl der zu prüfenden Signaturen, gefolgt von einem einzelnen Padding-Byte. Danach wird die folgende Struktur einmal pro Signatur serialisiert:

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-Wiederherstellung verifizieren

Das secp256k1-Programm verifiziert secp256k1-Public-Key-Wiederherstellungsoperationen (ecrecover).

ProgrammProgramm-IDBeschreibungAnweisungenQuelle
Secp256k1-ProgrammKeccakSecp256k11111111111111111111111111111Verifiziert secp256k1-Public-Key-Wiederherstellungsoperationen (ecrecover).AnweisungenQuelle

Das erste Byte der Anweisung enthält die Anzahl der zu prüfenden öffentlichen Schlüssel. Danach wird die folgende Struktur einmal pro öffentlichem Schlüssel serialisiert:

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
}

Signatur- und Nachrichtendaten können auf beliebige Anweisungsdaten in der Transaktion verweisen. Durch Angabe des speziellen Instructions-Sysvars können Programme auch Daten aus der Transaktion selbst lesen.

Die Transaktionskosten entsprechen der Anzahl der zu verifizierenden Signaturen multipliziert mit den Kosten pro Signaturverifizierung.

Secp256r1-Signatur verifizieren

Das Secp256r1-Programm verifiziert bis zu 8 Secp256r1-Signaturen pro Anweisung.

ProgrammProgramm-IDBeschreibungAnweisungenQuelle
Secp256r1-ProgrammSecp256r1SigVerify1111111111111111111111111Verifiziert bis zu 8 Secp256r1-Signaturen. Nimmt eine Signatur, einen öffentlichen Schlüssel und eine Nachricht entgegen. Gibt einen Fehler zurück, falls eine fehlschlägt.AnweisungenQuelle

Das erste u8 der Anweisung ist eine Anzahl der zu prüfenden Signaturen, gefolgt von einem einzelnen Padding-Byte. Danach wird die folgende Struktur einmal pro Signatur serialisiert:

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
}

Niedrige S-Werte werden für alle Signaturen erzwungen, um versehentliche Signatur-Formbarkeit zu vermeiden.

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?

Inhaltsverzeichnis

Seite bearbeiten

Verwaltet von

© 2026 Solana Foundation.
Alle Rechte vorbehalten.
Verbinden Sie sich