Line data Source code
1 : #include "fd_vm_syscall.h"
2 :
3 : #include "../../../ballet/keccak256/fd_keccak256.h"
4 :
5 : /* Syscalls for sha256, keccak256, blake3. */
6 :
7 : /* Agave has a single generic hash syscall:
8 : https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1895-L1959
9 : With trait impl for sha256, keccak256 and blake3:
10 : https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L130-L225
11 :
12 : Notes:
13 : 1. Max slices, base cost and byte cost are the same for all 3 hash functions:
14 : - https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L189-L197
15 : - https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L216-L224
16 : 2. Poseidon doesn't follow this generic hash implementation (so we left it in fd_vm_syscall_crypto.c):
17 : - https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1678
18 :
19 : Implementation notes.
20 : Because of the notes above, we implemented fd_vm_syscall_sol_sha256() following the generic hash
21 : syscall step by step.
22 : The other implementations are just a copy & paste, replacing the hash function.
23 : Resisted the temptation to do a macro, because it would complicate future changes, for example if
24 : we were to modify CU costs. */
25 :
26 : int
27 : fd_vm_syscall_sol_sha256( /**/ void * _vm,
28 : /**/ ulong vals_addr,
29 : /**/ ulong vals_len,
30 : /**/ ulong result_addr,
31 : FD_PARAM_UNUSED ulong r4,
32 : FD_PARAM_UNUSED ulong r5,
33 0 : /**/ ulong * _ret ) {
34 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1897 */
35 0 : fd_vm_t * vm = (fd_vm_t *)_vm;
36 :
37 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1911-L1920 */
38 0 : if( FD_UNLIKELY( FD_VM_SHA256_MAX_SLICES < vals_len ) ) {
39 : /* Max msg_sz = 61 - 8 + 6 + 20 + 20 = 99 < 127 => we can use printf */
40 0 : fd_log_collector_printf_dangerous_max_127( vm->instr_ctx,
41 0 : "%s Hashing %lu sequences in one syscall is over the limit %lu",
42 0 : "Sha256", vals_len, FD_VM_SHA256_MAX_SLICES );
43 0 : FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_TOO_MANY_SLICES );
44 0 : return FD_VM_SYSCALL_ERR_TOO_MANY_SLICES; /* SyscallError::TooManySlices */
45 0 : }
46 :
47 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1922 */
48 0 : FD_VM_CU_UPDATE( vm, FD_VM_SHA256_BASE_COST );
49 :
50 : /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L2030-L2034 */
51 0 : fd_vm_haddr_query_t hash_result_query = {
52 0 : .vaddr = result_addr,
53 0 : .align = FD_VM_ALIGN_RUST_U8,
54 0 : .sz = 32UL,
55 0 : .is_slice = 1,
56 0 : };
57 :
58 0 : fd_vm_haddr_query_t * queries[] = { &hash_result_query };
59 0 : FD_VM_TRANSLATE_MUT( vm, queries );
60 :
61 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1930 */
62 0 : fd_sha256_t sha[1];
63 0 : fd_sha256_init( sha );
64 :
65 0 : if( vals_len > 0 ) {
66 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1932-L1937 */
67 0 : fd_vm_vec_t const * input_vec_haddr = (fd_vm_vec_t const *)FD_VM_MEM_HADDR_LD( vm, vals_addr, FD_VM_VEC_ALIGN, vals_len*sizeof(fd_vm_vec_t) );
68 0 : for( ulong i=0UL; i<vals_len; i++ ) {
69 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1939-L1944 */
70 0 : ulong val_len = input_vec_haddr[i].len;
71 0 : void const * bytes = FD_VM_MEM_SLICE_HADDR_LD( vm, input_vec_haddr[i].addr, FD_VM_ALIGN_RUST_U8, val_len );
72 :
73 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1945-L1951 */
74 0 : ulong cost = fd_ulong_max( FD_VM_MEM_OP_BASE_COST,
75 0 : fd_ulong_sat_mul( FD_VM_SHA256_BYTE_COST, (val_len / 2) ) );
76 :
77 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1952 */
78 0 : FD_VM_CU_UPDATE( vm, cost );
79 :
80 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1953 */
81 0 : fd_sha256_append( sha, bytes, val_len );
82 0 : }
83 0 : }
84 :
85 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1956-L1957 */
86 0 : fd_sha256_fini( sha, hash_result_query.haddr );
87 0 : *_ret = 0UL;
88 0 : return FD_VM_SUCCESS;
89 0 : }
90 :
91 : int
92 : fd_vm_syscall_sol_blake3( /**/ void * _vm,
93 : /**/ ulong vals_addr,
94 : /**/ ulong vals_len,
95 : /**/ ulong result_addr,
96 : FD_PARAM_UNUSED ulong r4,
97 : FD_PARAM_UNUSED ulong r5,
98 0 : /**/ ulong * _ret ) {
99 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1897 */
100 0 : fd_vm_t * vm = (fd_vm_t *)_vm;
101 :
102 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1911-L1920 */
103 0 : if( FD_UNLIKELY( FD_VM_SHA256_MAX_SLICES < vals_len ) ) {
104 : /* Max msg_sz = 61 - 8 + 6 + 20 + 20 = 99 < 127 => we can use printf */
105 0 : fd_log_collector_printf_dangerous_max_127( vm->instr_ctx,
106 0 : "%s Hashing %lu sequences in one syscall is over the limit %lu",
107 0 : "Blake3", vals_len, FD_VM_SHA256_MAX_SLICES );
108 0 : FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_TOO_MANY_SLICES );
109 0 : return FD_VM_SYSCALL_ERR_TOO_MANY_SLICES; /* SyscallError::TooManySlices */
110 0 : }
111 :
112 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1922 */
113 0 : FD_VM_CU_UPDATE( vm, FD_VM_SHA256_BASE_COST );
114 :
115 : /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L2030-L2034 */
116 0 : fd_vm_haddr_query_t hash_result_query = {
117 0 : .vaddr = result_addr,
118 0 : .align = FD_VM_ALIGN_RUST_U8,
119 0 : .sz = 32UL,
120 0 : .is_slice = 1,
121 0 : };
122 :
123 0 : fd_vm_haddr_query_t * queries[] = { &hash_result_query };
124 0 : FD_VM_TRANSLATE_MUT( vm, queries );
125 :
126 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1930 */
127 0 : fd_blake3_t sha[1];
128 0 : fd_blake3_init( sha );
129 :
130 0 : if( vals_len > 0 ) {
131 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1932-L1937 */
132 0 : fd_vm_vec_t const * input_vec_haddr = (fd_vm_vec_t const *)FD_VM_MEM_HADDR_LD( vm, vals_addr, FD_VM_VEC_ALIGN, vals_len*sizeof(fd_vm_vec_t) );
133 0 : for( ulong i=0UL; i<vals_len; i++ ) {
134 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1939-L1944 */
135 0 : ulong val_len = input_vec_haddr[i].len;
136 0 : void const * bytes = FD_VM_MEM_SLICE_HADDR_LD( vm, input_vec_haddr[i].addr, FD_VM_ALIGN_RUST_U8, val_len );
137 :
138 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1945-L1951 */
139 0 : ulong cost = fd_ulong_max( FD_VM_MEM_OP_BASE_COST,
140 0 : fd_ulong_sat_mul( FD_VM_SHA256_BYTE_COST, (val_len / 2) ) );
141 :
142 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1952 */
143 0 : FD_VM_CU_UPDATE( vm, cost );
144 :
145 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1953 */
146 0 : fd_blake3_append( sha, bytes, val_len );
147 0 : }
148 0 : }
149 :
150 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1956-L1957 */
151 0 : fd_blake3_fini( sha, hash_result_query.haddr );
152 0 : *_ret = 0UL;
153 0 : return FD_VM_SUCCESS;
154 0 : }
155 :
156 : int
157 : fd_vm_syscall_sol_keccak256( /**/ void * _vm,
158 : /**/ ulong vals_addr,
159 : /**/ ulong vals_len,
160 : /**/ ulong result_addr,
161 : FD_PARAM_UNUSED ulong r4,
162 : FD_PARAM_UNUSED ulong r5,
163 0 : /**/ ulong * _ret ) {
164 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1897 */
165 0 : fd_vm_t * vm = (fd_vm_t *)_vm;
166 :
167 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1911-L1920 */
168 0 : if( FD_UNLIKELY( FD_VM_SHA256_MAX_SLICES < vals_len ) ) {
169 : /* Max msg_sz = 61 - 8 + 9 + 20 + 20 = 102 < 127 => we can use printf */
170 0 : fd_log_collector_printf_dangerous_max_127( vm->instr_ctx,
171 0 : "%s Hashing %lu sequences in one syscall is over the limit %lu",
172 0 : "Keccak256", vals_len, FD_VM_SHA256_MAX_SLICES );
173 0 : FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_SYSCALL_ERR_TOO_MANY_SLICES );
174 0 : return FD_VM_SYSCALL_ERR_TOO_MANY_SLICES; /* SyscallError::TooManySlices */
175 0 : }
176 :
177 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1922 */
178 0 : FD_VM_CU_UPDATE( vm, FD_VM_SHA256_BASE_COST );
179 :
180 : /* https://github.com/anza-xyz/agave/blob/v2.3.1/programs/bpf_loader/src/syscalls/mod.rs#L2030-L2034 */
181 0 : fd_vm_haddr_query_t hash_result_query = {
182 0 : .vaddr = result_addr,
183 0 : .align = FD_VM_ALIGN_RUST_U8,
184 0 : .sz = 32UL,
185 0 : .is_slice = 1,
186 0 : };
187 :
188 0 : fd_vm_haddr_query_t * queries[] = { &hash_result_query };
189 0 : FD_VM_TRANSLATE_MUT( vm, queries );
190 :
191 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1930 */
192 0 : fd_keccak256_t sha[1];
193 0 : fd_keccak256_init( sha );
194 :
195 0 : if( vals_len > 0 ) {
196 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1932-L1937 */
197 0 : fd_vm_vec_t const * input_vec_haddr = (fd_vm_vec_t const *)FD_VM_MEM_HADDR_LD( vm, vals_addr, FD_VM_VEC_ALIGN, vals_len*sizeof(fd_vm_vec_t) );
198 0 : for( ulong i=0UL; i<vals_len; i++ ) {
199 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1939-L1944 */
200 0 : ulong val_len = input_vec_haddr[i].len;
201 0 : void const * bytes = FD_VM_MEM_SLICE_HADDR_LD( vm, input_vec_haddr[i].addr, FD_VM_ALIGN_RUST_U8, val_len );
202 :
203 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1945-L1951 */
204 0 : ulong cost = fd_ulong_max( FD_VM_MEM_OP_BASE_COST,
205 0 : fd_ulong_sat_mul( FD_VM_SHA256_BYTE_COST, (val_len / 2) ) );
206 :
207 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1952 */
208 0 : FD_VM_CU_UPDATE( vm, cost );
209 :
210 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1953 */
211 0 : fd_keccak256_append( sha, bytes, val_len );
212 0 : }
213 0 : }
214 :
215 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1956-L1957 */
216 0 : fd_keccak256_fini( sha, hash_result_query.haddr );
217 0 : *_ret = 0UL;
218 0 : return FD_VM_SUCCESS;
219 0 : }
|