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.
| Programm | Programm-ID | Beschreibung | Anweisungen | Quelle |
|---|---|---|---|---|
| Ed25519-Programm | Ed25519SigVerify111111111111111111111111111 | Verifiziert ed25519-Signaturen. Wenn eine Signatur fehlschlägt, wird ein Fehler zurückgegeben. | Anweisungen | Quelle |
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:
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-Wiederherstellung verifizieren
Das secp256k1-Programm verifiziert secp256k1-Public-Key-Wiederherstellungsoperationen (ecrecover).
| Programm | Programm-ID | Beschreibung | Anweisungen | Quelle |
|---|---|---|---|---|
| Secp256k1-Programm | KeccakSecp256k11111111111111111111111111111 | Verifiziert secp256k1-Public-Key-Wiederherstellungsoperationen (ecrecover). | Anweisungen | Quelle |
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:
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}
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.
| Programm | Programm-ID | Beschreibung | Anweisungen | Quelle |
|---|---|---|---|---|
| Secp256r1-Programm | Secp256r1SigVerify1111111111111111111111111 | Verifiziert 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. | Anweisungen | Quelle |
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:
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}
Niedrige S-Werte werden für alle Signaturen erzwungen, um versehentliche Signatur-Formbarkeit zu vermeiden.
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?