Simplify ed25519 instruction index
Allow u16::MAX to be specified for the instruction index. This makes it possible to specify the current instruction, so it is not necessary to know the instruction number.
This commit is contained in:
@ -71,7 +71,7 @@ Verify ed25519 signature program. This program takes an ed25519 signature, publi
|
|||||||
Multiple signatures can be verified. If any of the signatures fail to verify, an error is returned.
|
Multiple signatures can be verified. If any of the signatures fail to verify, an error is returned.
|
||||||
|
|
||||||
- Program id: `Ed25519SigVerify111111111111111111111111111`
|
- Program id: `Ed25519SigVerify111111111111111111111111111`
|
||||||
- Instructions: [new_ed25519_instruction](https://github.com/solana-labs/solana/blob/master/sdk/src/ed25519_instruction.rs#L31)
|
- Instructions: [new_ed25519_instruction](https://github.com/solana-labs/solana/blob/master/sdk/src/ed25519_instruction.rs#L45)
|
||||||
|
|
||||||
The ed25519 program processes an instruction. The first `u8` is a count of the number of
|
The ed25519 program processes an instruction. The first `u8` is a count of the number of
|
||||||
signatures to check, which is followed by a single byte padding. After that, the
|
signatures to check, which is followed by a single byte padding. After that, the
|
||||||
@ -96,9 +96,12 @@ process_instruction() {
|
|||||||
for i in 0..count {
|
for i in 0..count {
|
||||||
// i'th index values referenced:
|
// i'th index values referenced:
|
||||||
instructions = &transaction.message().instructions
|
instructions = &transaction.message().instructions
|
||||||
signature = instructions[ed25519_signature_instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]
|
instruction_index = ed25519_signature_instruction_index != u16::MAX ? ed25519_signature_instruction_index : current_instruction;
|
||||||
pubkey = instructions[ed25519_pubkey_instruction_index].data[ed25519_pubkey_offset..ed25519_pubkey_offset + 32]
|
signature = instructions[instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]
|
||||||
message = instructions[ed25519_message_instruction_index].data[ed25519_message_data_offset..ed25519_message_data_offset + ed25519_message_data_size]
|
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 {
|
if pubkey.verify(signature, message) != Success {
|
||||||
return Error
|
return Error
|
||||||
}
|
}
|
||||||
|
@ -48,12 +48,12 @@ pub fn new_ed25519_instruction(keypair: &ed25519_dalek::Keypair, message: &[u8])
|
|||||||
|
|
||||||
let offsets = Ed25519SignatureOffsets {
|
let offsets = Ed25519SignatureOffsets {
|
||||||
signature_offset: signature_offset as u16,
|
signature_offset: signature_offset as u16,
|
||||||
signature_instruction_index: 0,
|
signature_instruction_index: u16::MAX,
|
||||||
public_key_offset: public_key_offset as u16,
|
public_key_offset: public_key_offset as u16,
|
||||||
public_key_instruction_index: 0,
|
public_key_instruction_index: u16::MAX,
|
||||||
message_data_offset: message_data_offset as u16,
|
message_data_offset: message_data_offset as u16,
|
||||||
message_data_size: message.len() as u16,
|
message_data_size: message.len() as u16,
|
||||||
message_instruction_index: 0,
|
message_instruction_index: u16::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
instruction_data.extend_from_slice(bytes_of(&offsets));
|
instruction_data.extend_from_slice(bytes_of(&offsets));
|
||||||
@ -106,23 +106,20 @@ pub fn verify(
|
|||||||
.map_err(|_| PrecompileError::InvalidDataOffsets)?;
|
.map_err(|_| PrecompileError::InvalidDataOffsets)?;
|
||||||
|
|
||||||
// Parse out signature
|
// Parse out signature
|
||||||
let signature_index = offsets.signature_instruction_index as usize;
|
let signature = get_data_slice(
|
||||||
if signature_index >= instruction_datas.len() {
|
data,
|
||||||
return Err(PrecompileError::InvalidDataOffsets);
|
instruction_datas,
|
||||||
}
|
offsets.signature_instruction_index,
|
||||||
let signature_instruction = instruction_datas[signature_index];
|
offsets.signature_offset,
|
||||||
let sig_start = offsets.signature_offset as usize;
|
SIGNATURE_SERIALIZED_SIZE,
|
||||||
let sig_end = sig_start.saturating_add(SIGNATURE_SERIALIZED_SIZE);
|
)?;
|
||||||
if sig_end >= signature_instruction.len() {
|
|
||||||
return Err(PrecompileError::InvalidDataOffsets);
|
|
||||||
}
|
|
||||||
|
|
||||||
let signature =
|
let signature = ed25519_dalek::Signature::from_bytes(signature)
|
||||||
ed25519_dalek::Signature::from_bytes(&signature_instruction[sig_start..sig_end])
|
|
||||||
.map_err(|_| PrecompileError::InvalidSignature)?;
|
.map_err(|_| PrecompileError::InvalidSignature)?;
|
||||||
|
|
||||||
// Parse out pubkey
|
// Parse out pubkey
|
||||||
let pubkey = get_data_slice(
|
let pubkey = get_data_slice(
|
||||||
|
data,
|
||||||
instruction_datas,
|
instruction_datas,
|
||||||
offsets.public_key_instruction_index,
|
offsets.public_key_instruction_index,
|
||||||
offsets.public_key_offset,
|
offsets.public_key_offset,
|
||||||
@ -134,6 +131,7 @@ pub fn verify(
|
|||||||
|
|
||||||
// Parse out message
|
// Parse out message
|
||||||
let message = get_data_slice(
|
let message = get_data_slice(
|
||||||
|
data,
|
||||||
instruction_datas,
|
instruction_datas,
|
||||||
offsets.message_instruction_index,
|
offsets.message_instruction_index,
|
||||||
offsets.message_data_offset,
|
offsets.message_data_offset,
|
||||||
@ -148,23 +146,29 @@ pub fn verify(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_data_slice<'a>(
|
fn get_data_slice<'a>(
|
||||||
|
data: &'a [u8],
|
||||||
instruction_datas: &'a [&[u8]],
|
instruction_datas: &'a [&[u8]],
|
||||||
instruction_index: u16,
|
instruction_index: u16,
|
||||||
offset_start: u16,
|
offset_start: u16,
|
||||||
size: usize,
|
size: usize,
|
||||||
) -> Result<&'a [u8], PrecompileError> {
|
) -> Result<&'a [u8], PrecompileError> {
|
||||||
|
let instruction = if instruction_index == u16::MAX {
|
||||||
|
data
|
||||||
|
} else {
|
||||||
let signature_index = instruction_index as usize;
|
let signature_index = instruction_index as usize;
|
||||||
if signature_index >= instruction_datas.len() {
|
if signature_index >= instruction_datas.len() {
|
||||||
return Err(PrecompileError::InvalidDataOffsets);
|
return Err(PrecompileError::InvalidDataOffsets);
|
||||||
}
|
}
|
||||||
let signature_instruction = &instruction_datas[signature_index];
|
&instruction_datas[signature_index]
|
||||||
|
};
|
||||||
|
|
||||||
let start = offset_start as usize;
|
let start = offset_start as usize;
|
||||||
let end = start.saturating_add(size);
|
let end = start.saturating_add(size);
|
||||||
if end > signature_instruction.len() {
|
if end > instruction.len() {
|
||||||
return Err(PrecompileError::InvalidDataOffsets);
|
return Err(PrecompileError::InvalidDataOffsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(&instruction_datas[signature_index][start..end])
|
Ok(&instruction[start..end])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
Reference in New Issue
Block a user