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 48 : /**/ ulong * _ret ) {
34 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1897 */
35 48 : 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 48 : 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 3 : fd_log_collector_printf_dangerous_max_127( vm->instr_ctx,
41 3 : "%s Hashing %lu sequences in one syscall is over the limit %lu",
42 3 : "Sha256", vals_len, FD_VM_SHA256_MAX_SLICES );
43 3 : FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_ERR_SYSCALL_TOO_MANY_SLICES );
44 3 : return FD_VM_ERR_INVAL; /* SyscallError::TooManySlices */
45 3 : }
46 :
47 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1922 */
48 87 : FD_VM_CU_UPDATE( vm, FD_VM_SHA256_BASE_COST );
49 :
50 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1924-L1929 */
51 108 : void * hash_result = FD_VM_MEM_HADDR_ST( vm, result_addr, FD_VM_ALIGN_RUST_U8, 32UL );
52 :
53 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1930 */
54 0 : fd_sha256_t sha[1];
55 108 : fd_sha256_init( sha );
56 :
57 108 : if( vals_len > 0 ) {
58 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1932-L1937 */
59 78 : 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) );
60 42 : for( ulong i=0UL; i<vals_len; i++ ) {
61 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1939-L1944 */
62 30 : ulong val_len = input_vec_haddr[i].len;
63 54 : void const * bytes = FD_VM_MEM_SLICE_HADDR_LD( vm, input_vec_haddr[i].addr, FD_VM_ALIGN_RUST_U8, val_len );
64 :
65 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1945-L1951 */
66 24 : ulong cost = fd_ulong_max( FD_VM_MEM_OP_BASE_COST,
67 54 : fd_ulong_sat_mul( FD_VM_SHA256_BYTE_COST, (val_len / 2) ) );
68 :
69 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1952 */
70 54 : FD_VM_CU_UPDATE( vm, cost );
71 :
72 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1953 */
73 0 : fd_sha256_append( sha, bytes, val_len );
74 18 : }
75 78 : }
76 :
77 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1956-L1957 */
78 15 : fd_sha256_fini( sha, hash_result );
79 15 : *_ret = 0UL;
80 15 : return FD_VM_SUCCESS;
81 108 : }
82 :
83 : int
84 : fd_vm_syscall_sol_blake3( /**/ void * _vm,
85 : /**/ ulong vals_addr,
86 : /**/ ulong vals_len,
87 : /**/ ulong result_addr,
88 : FD_PARAM_UNUSED ulong r4,
89 : FD_PARAM_UNUSED ulong r5,
90 48 : /**/ ulong * _ret ) {
91 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1897 */
92 48 : fd_vm_t * vm = (fd_vm_t *)_vm;
93 :
94 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1911-L1920 */
95 48 : if( FD_UNLIKELY( FD_VM_SHA256_MAX_SLICES < vals_len ) ) {
96 : /* Max msg_sz = 61 - 8 + 6 + 20 + 20 = 99 < 127 => we can use printf */
97 3 : fd_log_collector_printf_dangerous_max_127( vm->instr_ctx,
98 3 : "%s Hashing %lu sequences in one syscall is over the limit %lu",
99 3 : "Blake3", vals_len, FD_VM_SHA256_MAX_SLICES );
100 3 : FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_ERR_SYSCALL_TOO_MANY_SLICES );
101 3 : return FD_VM_ERR_INVAL; /* SyscallError::TooManySlices */
102 3 : }
103 :
104 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1922 */
105 87 : FD_VM_CU_UPDATE( vm, FD_VM_SHA256_BASE_COST );
106 :
107 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1924-L1929 */
108 108 : void * hash_result = FD_VM_MEM_HADDR_ST( vm, result_addr, FD_VM_ALIGN_RUST_U8, 32UL );
109 :
110 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1930 */
111 0 : fd_blake3_t sha[1];
112 108 : fd_blake3_init( sha );
113 :
114 108 : if( vals_len > 0 ) {
115 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1932-L1937 */
116 78 : 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) );
117 42 : for( ulong i=0UL; i<vals_len; i++ ) {
118 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1939-L1944 */
119 30 : ulong val_len = input_vec_haddr[i].len;
120 54 : void const * bytes = FD_VM_MEM_SLICE_HADDR_LD( vm, input_vec_haddr[i].addr, FD_VM_ALIGN_RUST_U8, val_len );
121 :
122 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1945-L1951 */
123 24 : ulong cost = fd_ulong_max( FD_VM_MEM_OP_BASE_COST,
124 54 : fd_ulong_sat_mul( FD_VM_SHA256_BYTE_COST, (val_len / 2) ) );
125 :
126 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1952 */
127 54 : FD_VM_CU_UPDATE( vm, cost );
128 :
129 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1953 */
130 0 : fd_blake3_append( sha, bytes, val_len );
131 18 : }
132 78 : }
133 :
134 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1956-L1957 */
135 15 : fd_blake3_fini( sha, hash_result );
136 15 : *_ret = 0UL;
137 15 : return FD_VM_SUCCESS;
138 108 : }
139 :
140 : int
141 : fd_vm_syscall_sol_keccak256( /**/ void * _vm,
142 : /**/ ulong vals_addr,
143 : /**/ ulong vals_len,
144 : /**/ ulong result_addr,
145 : FD_PARAM_UNUSED ulong r4,
146 : FD_PARAM_UNUSED ulong r5,
147 51 : /**/ ulong * _ret ) {
148 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1897 */
149 51 : fd_vm_t * vm = (fd_vm_t *)_vm;
150 :
151 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1911-L1920 */
152 51 : if( FD_UNLIKELY( FD_VM_SHA256_MAX_SLICES < vals_len ) ) {
153 : /* Max msg_sz = 61 - 8 + 9 + 20 + 20 = 102 < 127 => we can use printf */
154 3 : fd_log_collector_printf_dangerous_max_127( vm->instr_ctx,
155 3 : "%s Hashing %lu sequences in one syscall is over the limit %lu",
156 3 : "Keccak256", vals_len, FD_VM_SHA256_MAX_SLICES );
157 3 : FD_VM_ERR_FOR_LOG_SYSCALL( vm, FD_VM_ERR_SYSCALL_TOO_MANY_SLICES );
158 3 : return FD_VM_ERR_INVAL; /* SyscallError::TooManySlices */
159 3 : }
160 :
161 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1922 */
162 93 : FD_VM_CU_UPDATE( vm, FD_VM_SHA256_BASE_COST );
163 :
164 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1924-L1929 */
165 117 : void * hash_result = FD_VM_MEM_HADDR_ST( vm, result_addr, FD_VM_ALIGN_RUST_U8, 32UL );
166 :
167 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1930 */
168 0 : fd_keccak256_t sha[1];
169 117 : fd_keccak256_init( sha );
170 :
171 117 : if( vals_len > 0 ) {
172 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1932-L1937 */
173 87 : 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) );
174 51 : for( ulong i=0UL; i<vals_len; i++ ) {
175 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1939-L1944 */
176 36 : ulong val_len = input_vec_haddr[i].len;
177 66 : void const * bytes = FD_VM_MEM_SLICE_HADDR_LD( vm, input_vec_haddr[i].addr, FD_VM_ALIGN_RUST_U8, val_len );
178 :
179 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1945-L1951 */
180 30 : ulong cost = fd_ulong_max( FD_VM_MEM_OP_BASE_COST,
181 66 : fd_ulong_sat_mul( FD_VM_SHA256_BYTE_COST, (val_len / 2) ) );
182 :
183 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1952 */
184 66 : FD_VM_CU_UPDATE( vm, cost );
185 :
186 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1953 */
187 0 : fd_keccak256_append( sha, bytes, val_len );
188 24 : }
189 87 : }
190 :
191 : /* https://github.com/anza-xyz/agave/blob/v1.18.12/programs/bpf_loader/src/syscalls/mod.rs#L1956-L1957 */
192 18 : fd_keccak256_fini( sha, hash_result );
193 18 : *_ret = 0UL;
194 18 : return FD_VM_SUCCESS;
195 117 : }
|