solana_ed25519_program/
lib.rs1use {
6 bytemuck::bytes_of,
7 bytemuck_derive::{Pod, Zeroable},
8 solana_instruction::Instruction,
9};
10
11pub const PUBKEY_SERIALIZED_SIZE: usize = 32;
12pub const SIGNATURE_SERIALIZED_SIZE: usize = 64;
13pub const SIGNATURE_OFFSETS_SERIALIZED_SIZE: usize = 14;
14pub const SIGNATURE_OFFSETS_START: usize = 2;
16pub const DATA_START: usize = SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START;
17
18#[derive(Default, Debug, Copy, Clone, Zeroable, Pod, Eq, PartialEq)]
19#[repr(C)]
20pub struct Ed25519SignatureOffsets {
21 pub signature_offset: u16, pub signature_instruction_index: u16, pub public_key_offset: u16, pub public_key_instruction_index: u16, pub message_data_offset: u16, pub message_data_size: u16, pub message_instruction_index: u16, }
29
30pub fn offsets_to_ed25519_instruction(offsets: &[Ed25519SignatureOffsets]) -> Instruction {
40 let mut instruction_data = Vec::with_capacity(
41 SIGNATURE_OFFSETS_START
42 .saturating_add(SIGNATURE_OFFSETS_SERIALIZED_SIZE.saturating_mul(offsets.len())),
43 );
44
45 let num_signatures = offsets.len() as u16;
46 instruction_data.extend_from_slice(&num_signatures.to_le_bytes());
47
48 for offsets in offsets {
49 instruction_data.extend_from_slice(bytes_of(offsets));
50 }
51
52 Instruction {
53 program_id: solana_sdk_ids::ed25519_program::id(),
54 accounts: vec![],
55 data: instruction_data,
56 }
57}
58
59pub fn new_ed25519_instruction_with_signature(
60 message: &[u8],
61 signature: &[u8; SIGNATURE_SERIALIZED_SIZE],
62 pubkey: &[u8; PUBKEY_SERIALIZED_SIZE],
63) -> Instruction {
64 let mut instruction_data = Vec::with_capacity(
65 DATA_START
66 .saturating_add(SIGNATURE_SERIALIZED_SIZE)
67 .saturating_add(PUBKEY_SERIALIZED_SIZE)
68 .saturating_add(message.len()),
69 );
70
71 let num_signatures: u8 = 1;
72 let public_key_offset = DATA_START;
73 let signature_offset = public_key_offset.saturating_add(PUBKEY_SERIALIZED_SIZE);
74 let message_data_offset = signature_offset.saturating_add(SIGNATURE_SERIALIZED_SIZE);
75
76 instruction_data.extend_from_slice(bytes_of(&[num_signatures, 0]));
78
79 let offsets = Ed25519SignatureOffsets {
80 signature_offset: signature_offset as u16,
81 signature_instruction_index: u16::MAX,
82 public_key_offset: public_key_offset as u16,
83 public_key_instruction_index: u16::MAX,
84 message_data_offset: message_data_offset as u16,
85 message_data_size: message.len() as u16,
86 message_instruction_index: u16::MAX,
87 };
88
89 instruction_data.extend_from_slice(bytes_of(&offsets));
90
91 debug_assert_eq!(instruction_data.len(), public_key_offset);
92
93 instruction_data.extend_from_slice(pubkey);
94
95 debug_assert_eq!(instruction_data.len(), signature_offset);
96
97 instruction_data.extend_from_slice(signature);
98
99 debug_assert_eq!(instruction_data.len(), message_data_offset);
100
101 instruction_data.extend_from_slice(message);
102
103 Instruction {
104 program_id: solana_sdk_ids::ed25519_program::id(),
105 accounts: vec![],
106 data: instruction_data,
107 }
108}