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.
| Programma | Programma-ID | Beschrijving | Instructies | Bron |
|---|---|---|---|---|
| Ed25519-programma | Ed25519SigVerify111111111111111111111111111 | Verifieert ed25519-handtekeningen. Als een handtekening faalt, wordt een fout geretourneerd. | Instructies | Bron |
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:
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-herstel verifiëren
Het secp256k1-programma verifieert secp256k1 public key recovery-operaties (ecrecover).
| Programma | Programma-ID | Beschrijving | Instructies | Bron |
|---|---|---|---|---|
| Secp256k1-programma | KeccakSecp256k11111111111111111111111111111 | Verifieert secp256k1 public key recovery-operaties (ecrecover). | Instructies | Bron |
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:
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}
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.
| Programma | Programma-ID | Beschrijving | Instructies | Bron |
|---|---|---|---|---|
| Secp256r1-programma | Secp256r1SigVerify1111111111111111111111111 | Verifieert maximaal 8 secp256r1-handtekeningen. Neemt een handtekening, publieke sleutel en bericht. Geeft een fout als een verificatie mislukt. | Instructies | Bron |
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:
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}
Lage S-waarden worden afgedwongen voor alle handtekeningen om onbedoelde handtekeningveranderlijkheid te voorkomen.
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?