solana_ed25519_instruction/
lib.rs

1#[cfg(feature = "anchor")]
2use anchor_lang::prelude::*;
3#[cfg(not(feature = "anchor"))]
4use solana_program::pubkey::Pubkey;
5use borsh::BorshDeserialize;
6
7
8#[derive(Debug)]
9pub struct Ed25519Signature(pub Vec<Ed25519SignatureOffsets>);
10
11impl BorshDeserialize for Ed25519Signature {
12    fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::result::Result<Ed25519Signature, std::io::Error> {
13        let header = Ed25519SignatureHeader::deserialize_reader(reader)?;
14        let mut offsets: Vec<Ed25519SignatureOffsets> = Vec::with_capacity(header.num_signatures as usize);
15        for _ in 0..header.num_signatures {
16            offsets.push(Ed25519SignatureOffsets::deserialize_reader(reader)?);
17        }
18        Ok(Self(offsets))
19    }
20}
21
22#[derive(BorshDeserialize, Debug)]
23pub struct Ed25519SignatureHeader {
24    pub num_signatures: u8,
25    pub padding: u8,
26}
27
28#[derive(BorshDeserialize, Debug)]
29pub struct Ed25519SignatureOffsets {
30    pub signature_offset: u16,
31    pub signature_instruction_index: u16,
32    pub public_key_offset: u16,
33    pub public_key_instruction_index: u16,
34    pub message_data_offset: u16,
35    pub message_data_size: u16,
36    pub message_instruction_index: u16
37}
38
39impl Ed25519SignatureOffsets {
40    pub fn get_signer(&self, data: &[u8]) -> &Pubkey {
41        let slice = &data[self.public_key_offset as usize..self.public_key_offset as usize + 32];
42        unsafe { &*(slice.as_ptr() as *const Pubkey) }
43    }
44
45    pub fn get_signature(&self, data: &[u8]) -> &[u8; 64] {
46        let slice = &data[self.signature_offset as usize..self.signature_offset as usize + 64];
47        unsafe { &*(slice.as_ptr() as *const [u8; 64]) }
48    }
49
50    pub fn get_data(&self, data: &[u8]) -> Vec<u8> {
51        data[self.message_data_offset as usize..self.message_data_offset as usize + self.message_data_size as usize].to_vec()
52    }
53}