-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstack_operation_instructions.v
559 lines (427 loc) · 14.9 KB
/
stack_operation_instructions.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
(*
This module includes the concrete definition of stack operation
instruction, their corresponding table and properties such as
commutativity and externals-independent.
*)
Require Import bbv.Word.
Require Import Coq.NArith.NArith.
Require Import Coq.ZArith.ZArith.
Require Import List.
Import ListNotations.
Require Import FORVES2.execution_state.
Import ExecutionState.
Require Import FORVES2.constants.
Import Constants.
Require Import FORVES2.program.
Import Program.
Module StackOpInstrs.
(* Some stack operation instructions are commutative, a property that
might be used when optimizing a block. The following definition models
this property. *)
Definition commutative_op (f : externals -> list EVMWord -> EVMWord) : Prop :=
forall (a b : EVMWord) (exts : externals), f exts [a;b] = f exts [b;a].
Definition exts_independent_op (f : externals -> list EVMWord -> EVMWord) : Prop :=
forall (l : list EVMWord) (exts1 exts2 : externals), f exts1 l = f exts2 l.
(* A total "map" *)
Definition map (K V : Type) : Type := K -> V.
(* An implementation of a stack operation instructions *)
Inductive stack_op_impl :=
| OpImp (n : nat) (f : externals -> list EVMWord -> EVMWord) (H_comm : option (commutative_op f)) (H_exts_ind: option (exts_independent_op f)).
Definition stack_op_instr_map := map stack_op_instr stack_op_impl.
Definition empty_imap {A : Type} (def : A) : map stack_op_instr A :=
(fun _ => def).
Definition updatei {A : Type} (m : map stack_op_instr A) (x : stack_op_instr) (v : A) :=
fun x' => if x =?i x' then v else m x'.
Notation "x '|->i' v ';' m" := (updatei m x v) (at level 100, v at next level, right associativity).
Notation "x '|->i' v" := (updatei (empty_imap (OpImp 0 (fun (_:externals) (_:list EVMWord) => WZero) None None)) x v) (at level 100).
(* =================================================================
*) (** ** Implementation of current instructions *)
Ltac comm_op_tac_trivial f H_comm_of_underlying_op :=
unfold commutative_op;
intros;
unfold f;
rewrite -> H_comm_of_underlying_op;
reflexivity.
Ltac exts_independent_tac f :=
unfold exts_independent_op;
intros;
unfold f;
reflexivity.
Definition evm_add (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wplus a b
| _ => WZero
end.
Lemma add_comm: commutative_op evm_add.
Proof.
comm_op_tac_trivial evm_add wplus_comm.
Qed.
Lemma add_exts_ind: exts_independent_op evm_add.
Proof.
exts_independent_tac evm_add.
Qed.
Definition evm_mul (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wmult a b
| _ => WZero
end.
Lemma mul_comm: commutative_op evm_mul.
Proof.
comm_op_tac_trivial evm_mul wmult_comm.
Qed.
Lemma mul_exts_ind: exts_independent_op evm_mul.
Proof.
exts_independent_tac evm_mul.
Qed.
Definition evm_sub (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wminus a b
| _ => WZero
end.
Lemma sub_exts_ind: exts_independent_op evm_sub.
Proof.
exts_independent_tac evm_sub.
Qed.
Definition evm_div (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wdiv a b
| _ => WZero
end.
Lemma div_exts_ind: exts_independent_op evm_div.
Proof.
exts_independent_tac evm_div.
Qed.
Definition evm_sdiv (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_mod (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => if weqb b WZero then WZero else wmod a b
| _ => WZero
end.
Lemma mod_exts_ind: exts_independent_op evm_mod.
Proof.
exts_independent_tac evm_mod.
Qed.
Definition evm_smod (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_addmod (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b;c] => wmod (wplus a b) c
| _ => WZero
end.
Lemma addmod_exts_ind: exts_independent_op evm_addmod.
Proof.
exts_independent_tac evm_addmod.
Qed.
Definition evm_mulmod (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b;c] => wmod (wmult a b) c
| _ => WZero
end.
Lemma mulmod_exts_ind: exts_independent_op evm_mulmod.
Proof.
exts_independent_tac evm_mulmod.
Qed.
Definition evm_exp (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wordBin N.pow a b
| _ => WZero
end.
Lemma exp_exts_ind: exts_independent_op evm_exp.
Proof.
exts_independent_tac evm_exp.
Qed.
Definition evm_signextend (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_lt (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => if (N.ltb (wordToN a) (wordToN b)) then WOne else WZero
| _ => WZero
end.
Lemma lt_exts_ind: exts_independent_op evm_lt.
Proof.
exts_independent_tac evm_lt.
Qed.
Definition evm_gt (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => evm_lt exts [b; a]
| _ => WZero
end.
Lemma gt_exts_ind: exts_independent_op evm_gt.
Proof.
exts_independent_tac evm_gt.
Qed.
Definition evm_slt (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a; b] => if (Z.ltb (wordToZ a) (wordToZ b)) then WOne else WZero
| _ => WZero
end.
Lemma slt_exts_ind: exts_independent_op evm_slt.
Proof.
exts_independent_tac evm_slt.
Qed.
Definition evm_sgt (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => evm_slt exts [b; a]
| _ => WZero
end.
Lemma sgt_exts_ind: exts_independent_op evm_gt.
Proof.
exts_independent_tac evm_sgt.
Qed.
Definition evm_eq (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => if weqb a b then WOne else WZero
| _ => WZero
end.
Lemma eq_comm: commutative_op evm_eq.
Proof.
unfold commutative_op. intros a b exts.
unfold evm_eq.
destruct (weqb a b) eqn: eq_weqb_a_b.
- apply weqb_sound in eq_weqb_a_b.
symmetry in eq_weqb_a_b.
rewrite <- weqb_true_iff in eq_weqb_a_b.
rewrite -> eq_weqb_a_b.
reflexivity.
- apply weqb_false in eq_weqb_a_b.
apply not_eq_sym in eq_weqb_a_b.
apply weqb_ne in eq_weqb_a_b.
rewrite -> eq_weqb_a_b.
reflexivity.
Qed.
Lemma eq_exts_ind: exts_independent_op evm_eq.
Proof.
exts_independent_tac evm_eq.
Qed.
Definition evm_iszero (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a] => evm_eq exts [a; WZero]
| _ => WZero
end.
Lemma iszero_exts_ind: exts_independent_op evm_iszero.
Proof.
exts_independent_tac evm_iszero.
Qed.
Definition evm_and (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wand a b
| _ => WZero
end.
Lemma and_comm: commutative_op evm_and.
Proof.
comm_op_tac_trivial evm_and wand_comm.
Qed.
Lemma and_exts_ind: exts_independent_op evm_and.
Proof.
exts_independent_tac evm_and.
Qed.
Definition evm_or (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wor a b
| _ => WZero
end.
Lemma or_comm: commutative_op evm_or.
Proof.
comm_op_tac_trivial evm_or wor_comm.
Qed.
Lemma or_exts_ind: exts_independent_op evm_or.
Proof.
exts_independent_tac evm_or.
Qed.
Definition evm_xor (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wxor a b
| _ => WZero
end.
Lemma xor_comm: commutative_op evm_xor.
Proof.
comm_op_tac_trivial evm_xor wxor_comm.
Qed.
Lemma xor_exts_ind: exts_independent_op evm_xor.
Proof.
exts_independent_tac evm_xor.
Qed.
Definition evm_not (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a] => wnot a
| _ => WZero
end.
Lemma not_exts_ind: exts_independent_op evm_not.
Proof.
exts_independent_tac evm_not.
Qed.
Definition evm_byte (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_shl (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wlshift' b (wordToNat a)
| _ => WZero
end.
Lemma shl_exts_ind: exts_independent_op evm_shl.
Proof.
exts_independent_tac evm_shl.
Qed.
(* Equivalent definition better suited for the DIV_SHL optimization *)
Definition evm_shr (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [shift;value] => wdiv value (wlshift' WOne (wordToNat shift))
| _ => WZero
end.
(*
Definition evm_shr (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a;b] => wrshift' b (wordToNat a)
| _ => WZero
end.*)
Lemma shr_exts_ind: exts_independent_op evm_shr.
Proof.
exts_independent_tac evm_shr.
Qed.
Definition evm_sar (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_address (exts : externals) (args : list EVMWord) : EVMWord :=
let diff := EVMWordSize - EVMAddrSize in
zext (get_address_exts exts) diff.
Definition evm_balance (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a] => let diff := EVMWordSize - EVMAddrSize in
let address := split1 EVMAddrSize diff a in
(get_balance_exts exts) address
| _ => WZero
end.
Definition evm_origin (exts : externals) (args : list EVMWord) : EVMWord :=
let diff := EVMWordSize - EVMAddrSize in
zext (get_origin_exts exts) diff.
Definition evm_caller (exts : externals) (args : list EVMWord) : EVMWord :=
let diff := EVMWordSize - EVMAddrSize in
zext (get_caller_exts exts) diff.
Definition evm_callvalue (exts : externals) (args : list EVMWord) : EVMWord :=
get_callvalue_exts exts.
Definition evm_calldataload (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_calldatasize (exts : externals) (args : list EVMWord) : EVMWord :=
match get_data_exts exts with
| Chunk size data => natToWord EVMWordSize size
end.
Definition evm_codesize (exts : externals) (args : list EVMWord) : EVMWord :=
let address := get_address_exts exts in
let info := (get_code_exts exts) address in
match info with
| CodeInfo size content hash => natToWord EVMWordSize size
end.
Definition evm_gasprice (exts : externals) (args : list EVMWord) : EVMWord :=
get_gasprice_exts exts.
Definition evm_extcodesize (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a] => let diff := EVMWordSize - EVMAddrSize in
let address := split1 EVMAddrSize diff a in
let info := (get_code_exts exts) address in
match info with
| CodeInfo size content hash => natToWord EVMWordSize size
end
| _ => WZero
end.
Definition evm_returndatasize (exts : externals) (args : list EVMWord) : EVMWord :=
match get_outdata_exts exts with
| Chunk size data => natToWord EVMWordSize size
end.
Definition evm_extcodehash (exts : externals) (args : list EVMWord) : EVMWord :=
match args with
| [a] => let diff := EVMWordSize - EVMAddrSize in
let address := split1 EVMAddrSize diff a in
let info := (get_code_exts exts) address in
match info with
| CodeInfo size content hash => hash
end
| _ => WZero
end.
Definition evm_blockhash (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_coinbase (exts : externals) (args : list EVMWord) : EVMWord :=
let diff := EVMWordSize - EVMAddrSize in
zext (get_miner_exts exts) diff.
Definition evm_timestamp (exts : externals) (args : list EVMWord) : EVMWord :=
let curr_block := get_currblock_exts exts in
let info := (get_blocks_exts exts) curr_block in
match info with
| BlockInfo size content timestamp hash => timestamp
end.
Definition evm_number (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_difficulty (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Definition evm_gaslimit (exts : externals) (args : list EVMWord) : EVMWord :=
get_gaslimit_exts exts.
Definition evm_chainid (exts : externals) (args : list EVMWord) : EVMWord :=
get_chainid_exts exts.
Definition evm_selfbalance (exts : externals) (args : list EVMWord) : EVMWord :=
let address := get_address_exts exts in
(get_balance_exts exts) address.
Definition evm_basefee (exts : externals) (args : list EVMWord) : EVMWord :=
get_basefee_exts exts.
Definition evm_gas (exts : externals) (args : list EVMWord) : EVMWord :=
WZero.
Lemma gas_exts_ind: exts_independent_op evm_gas.
Proof.
exts_independent_tac evm_gas.
Qed.
Definition evm_jumpi (exts : externals) (args: list EVMWord) : EVMWord :=
match args with
| [a; b] => if weqb b WZero then WZero else a
| _ => WZero
end.
Lemma jumpi_exts_ind: exts_independent_op evm_jumpi.
Proof.
exts_independent_tac evm_jumpi.
Qed.
Definition evm_stack_opm : stack_op_instr_map :=
ADD |->i OpImp 2 evm_add (Some add_comm) (Some add_exts_ind);
MUL |->i OpImp 2 evm_mul (Some mul_comm) (Some mul_exts_ind);
SUB |->i OpImp 2 evm_sub None (Some sub_exts_ind);
DIV |->i OpImp 2 evm_div None (Some div_exts_ind);
SDIV |->i OpImp 2 evm_sdiv None None; (*TODO*)
MOD |->i OpImp 2 evm_mod None (Some mod_exts_ind);
SMOD |->i OpImp 2 evm_smod None None; (*TODO*)
ADDMOD |->i OpImp 3 evm_addmod None (Some addmod_exts_ind);
MULMOD |->i OpImp 3 evm_mulmod None (Some mulmod_exts_ind);
EXP |->i OpImp 2 evm_exp None (Some exp_exts_ind);
SIGNEXTEND |->i OpImp 2 evm_signextend None None; (*TODO*)
LT |->i OpImp 2 evm_lt None (Some lt_exts_ind);
GT |->i OpImp 2 evm_gt None (Some gt_exts_ind);
SLT |->i OpImp 2 evm_slt None (Some slt_exts_ind);
SGT |->i OpImp 2 evm_sgt None None; (*TODO*)
EQ |->i OpImp 2 evm_eq (Some eq_comm) (Some eq_exts_ind);
ISZERO |->i OpImp 1 evm_iszero None (Some iszero_exts_ind);
AND |->i OpImp 2 evm_and (Some and_comm) (Some and_exts_ind);
OR |->i OpImp 2 evm_or (Some or_comm) (Some or_exts_ind);
XOR |->i OpImp 2 evm_xor (Some xor_comm) (Some xor_exts_ind);
NOT |->i OpImp 1 evm_not None (Some not_exts_ind);
BYTE |->i OpImp 2 evm_byte None None; (*TODO*)
SHL |->i OpImp 2 evm_shl None (Some shl_exts_ind);
SHR |->i OpImp 2 evm_shr None (Some shr_exts_ind);
SAR |->i OpImp 2 evm_sar None None; (*TODO*)
ADDRESS |->i OpImp 0 evm_address None None;
BALANCE |->i OpImp 1 evm_balance None None;
ORIGIN |->i OpImp 0 evm_origin None None;
CALLER |->i OpImp 0 evm_caller None None;
CALLVALUE |->i OpImp 0 evm_callvalue None None;
CALLDATALOAD |->i OpImp 1 evm_calldataload None None; (*TODO*)
CALLDATASIZE |->i OpImp 0 evm_calldatasize None None;
CODESIZE |->i OpImp 0 evm_codesize None None;
GASPRICE |->i OpImp 0 evm_gasprice None None;
EXTCODESIZE |->i OpImp 1 evm_extcodesize None None;
RETURNDATASIZE |->i OpImp 0 evm_returndatasize None None;
EXTCODEHASH |->i OpImp 1 evm_extcodehash None None;
BLOCKHASH |->i OpImp 1 evm_blockhash None None; (*TODO*)
COINBASE |->i OpImp 0 evm_coinbase None None;
TIMESTAMP |->i OpImp 0 evm_timestamp None None;
NUMBER |->i OpImp 0 evm_number None None; (*TODO*)
DIFFICULTY |->i OpImp 0 evm_difficulty None None; (*TODO*)
GASLIMIT |->i OpImp 0 evm_gaslimit None None;
CHAINID |->i OpImp 0 evm_chainid None None;
SELFBALANCE |->i OpImp 0 evm_selfbalance None None;
BASEFEE |->i OpImp 0 evm_basefee None None;
GAS |->i OpImp 0 evm_gas None (Some gas_exts_ind);
JUMPI |->i OpImp 2 evm_jumpi None (Some jumpi_exts_ind).
End StackOpInstrs.