@@ -151,19 +151,14 @@ impl From<SignatureVerificationError> for anchor_lang::error::Error {
151151/// Verifies a ed25519 signature on Solana by checking that the transaction contains
152152/// a correct call to the built-in `ed25519_program`.
153153///
154- /// - `message_data` is the signed message that is being verified.
155154/// - `ed25519_instruction_index` is the index of the `ed25519_program` instruction
156155/// within the transaction. This instruction must precede the current instruction.
157156/// - `signature_index` is the index of the signature within the inputs to the `ed25519_program`.
158- /// - `message_offset` is the offset of the signed message within the
159- /// input data for the current instruction.
160157pub fn verify_message (
161158 storage : & Storage ,
162159 instructions_sysvar : & AccountInfo ,
163- message_data : & [ u8 ] ,
164160 ed25519_instruction_index : u16 ,
165161 signature_index : u8 ,
166- message_offset : u16 ,
167162) -> Result < VerifiedMessage , SignatureVerificationError > {
168163 const SOLANA_FORMAT_MAGIC_LE : u32 = 2182742457 ;
169164
@@ -175,25 +170,25 @@ pub fn verify_message(
175170 return Err ( SignatureVerificationError :: Ed25519InstructionMustPrecedeCurrentInstruction ) ;
176171 }
177172
178- let instruction = sysvar:: instructions:: load_instruction_at_checked (
173+ let ed25519_instruction = sysvar:: instructions:: load_instruction_at_checked (
179174 ed25519_instruction_index. into ( ) ,
180175 instructions_sysvar,
181176 )
182177 . map_err ( SignatureVerificationError :: LoadInstructionAtFailed ) ?;
183178
184- if instruction . program_id != ed25519_program:: ID {
179+ if ed25519_instruction . program_id != ed25519_program:: ID {
185180 return Err ( SignatureVerificationError :: InvalidEd25519InstructionProgramId ) ;
186181 }
187- if instruction . data . len ( ) < ED25519_PROGRAM_INPUT_HEADER_LEN {
182+ if ed25519_instruction . data . len ( ) < ED25519_PROGRAM_INPUT_HEADER_LEN {
188183 return Err ( SignatureVerificationError :: InvalidEd25519InstructionDataLength ) ;
189184 }
190185
191- let num_signatures = instruction . data [ 0 ] ;
186+ let num_signatures = ed25519_instruction . data [ 0 ] ;
192187 if signature_index >= num_signatures {
193188 return Err ( SignatureVerificationError :: InvalidSignatureIndex ) ;
194189 }
195190 let args: & [ Ed25519SignatureOffsets ] =
196- try_cast_slice ( & instruction . data [ ED25519_PROGRAM_INPUT_HEADER_LEN ..] )
191+ try_cast_slice ( & ed25519_instruction . data [ ED25519_PROGRAM_INPUT_HEADER_LEN ..] )
197192 . map_err ( |_| SignatureVerificationError :: InvalidEd25519InstructionDataLength ) ?;
198193
199194 let args_len = args
@@ -205,19 +200,41 @@ pub fn verify_message(
205200 }
206201 let offsets = & args[ usize:: from ( signature_index) ] ;
207202
208- let expected_signature_offset = message_offset
209- . checked_add ( MAGIC_LEN )
210- . ok_or ( SignatureVerificationError :: MessageOffsetOverflow ) ?;
211- if offsets. signature_offset != expected_signature_offset {
212- return Err ( SignatureVerificationError :: InvalidSignatureOffset ) ;
203+ if offsets. signature_instruction_index != offsets. message_instruction_index
204+ || offsets. public_key_instruction_index != offsets. message_instruction_index
205+ {
206+ return Err ( SignatureVerificationError :: InvalidInstructionIndex ) ;
213207 }
214208
209+ if ed25519_instruction_index >= offsets. message_instruction_index {
210+ return Err ( SignatureVerificationError :: Ed25519InstructionMustPrecedeCurrentInstruction ) ;
211+ }
212+ let message_instruction = sysvar:: instructions:: load_instruction_at_checked (
213+ offsets. message_instruction_index . into ( ) ,
214+ instructions_sysvar,
215+ )
216+ . map_err ( SignatureVerificationError :: LoadInstructionAtFailed ) ?;
217+
218+ let message_offset = offsets
219+ . signature_offset
220+ . checked_sub ( MAGIC_LEN )
221+ . ok_or ( SignatureVerificationError :: MessageOffsetOverflow ) ?;
222+ let message_end_offset = offsets
223+ . message_data_offset
224+ . checked_add ( offsets. message_data_size )
225+ . ok_or ( SignatureVerificationError :: MessageOffsetOverflow ) ?;
226+ let message_data = message_instruction
227+ . data
228+ . get ( usize:: from ( message_offset) ..usize:: from ( message_end_offset) )
229+ . ok_or ( SignatureVerificationError :: InvalidMessageOffset ) ?;
230+
215231 let magic = LE :: read_u32 ( & message_data[ ..MAGIC_LEN . into ( ) ] ) ;
216232 if magic != SOLANA_FORMAT_MAGIC_LE {
217233 return Err ( SignatureVerificationError :: FormatMagicMismatch ) ;
218234 }
219235
220- let expected_public_key_offset = expected_signature_offset
236+ let expected_public_key_offset = offsets
237+ . signature_offset
221238 . checked_add ( SIGNATURE_LEN )
222239 . ok_or ( SignatureVerificationError :: MessageOffsetOverflow ) ?;
223240 if offsets. public_key_offset != expected_public_key_offset {
@@ -251,12 +268,6 @@ pub fn verify_message(
251268 if offsets. message_data_size != expected_message_size {
252269 return Err ( SignatureVerificationError :: InvalidMessageDataSize ) ;
253270 }
254- if offsets. signature_instruction_index != self_instruction_index
255- || offsets. public_key_instruction_index != self_instruction_index
256- || offsets. message_instruction_index != self_instruction_index
257- {
258- return Err ( SignatureVerificationError :: InvalidInstructionIndex ) ;
259- }
260271
261272 let public_key = {
262273 let start = usize:: from (
0 commit comments