Open Scope Z.
(* Note: x must be non-zero, y is allowed to be zero (because x is a constant in all usages, its non-zero-check seems to be removed by the parser). *)
Definition mul_with_table(x y: Z)(pow: list int)(log: list Z): int :=
if Int.eq (if Int.eq (Int.repr y) Int.zero then Int.zero else Int.one) Int.zero
then Int.zero
else Znth (Int.unsigned
(Int.mods (Int.repr (Znth x log + Znth y log))
(Int.repr 255))) pow.
Definition Z_to_val(x: Z): val := if zeq x (-1) then Vundef else Vint (Int.repr x).
(* Calls forward_if with the current precondition to which the provided conditions are added *)
(* QQQ TODO does this already exist? Add to library? *)
Ltac forward_if_diff add := match add with
| (PROPx ?P2 (LOCALx ?Q2 (SEPx ?R2))) => match goal with
| |- semax ?Delta (PROPx ?P1 (LOCALx ?Q1 (SEPx ?R1))) _ _ =>
let P3 := fresh "P3" in let Q3 := fresh "Q3" in let R3 := fresh "R3" in
pose (P3 := P1 ++ P2); pose (Q3 := Q1 ++ Q2); pose (R3 := R1 ++ R2);
simpl in P3, Q3, R3;
forward_if (PROPx P3 (LOCALx Q3 (SEPx R3)));
subst P3 Q3 R3
end
end.
Definition rcon_loop_inv00(i: Z)(v_pow v_log: val)(gv: globals)(frozen: list mpred) : environ -> mpred :=
PROP ( 0 <= i) (* note: the upper bound is added by the tactic, but the lower isn't! *)
LOCAL (temp _x (Vint (pow2 i));
lvar _log (tarray tint 256) v_log;
lvar _pow (tarray tint 256) v_pow;
gvars gv)
SEP (FRZL frozen;
field_at Ews t_struct_tables [StructField _RCON]
((map Vint (repeat_op_table i Int.one times2)) ++ (repeat_op_table (10-i) Vundef id))
(gv _tables)).
Definition rcon_loop_inv0(v_pow v_log: val)(gv: globals)(frozen: list mpred) :=  EX i: Z,
rcon_loop_inv00 i v_pow v_log gv frozen.
(* TODO floyd if I inline inv00 into inv0, why doesn't this typecheck? Definition rcon_loop_inv(v_pow v_log tables: val) := EX i: Z, PROP ( 0 <= i) (* note: the upper bound is added by the tactic, but the lower isn't! *)
LOCAL (temp _x (Vint (pow2 i));
lvar _log (tarray tint 256) v_log;
lvar _pow (tarray tint 256) v_pow;
gvar _tables tables)
SEP (field_at Ews t_struct_tables [StructField _RCON]
((map Vint (repeat_op_table i Int.one times2)) ++ (repeat_op_table (10-i) Vundef id))
tables).
*)
Definition gen_sbox_inv00 i v_pow v_log log pow gv frozen :=
PROP ( )
LOCAL (lvar _log (tarray tint 256) v_log;
lvar _pow (tarray tint 256) v_pow;
gvars gv)
SEP (FRZL frozen; data_at Tsh (tarray tint 256) log v_log; data_at Tsh (tarray tint 256) pow v_pow;
EX fsb : list val,
!!(Zlength fsb = 256) &&
!!(forall j, 0 <= j < i -> Znth j fsb = Vint (Znth j FSb)) &&
!!(Znth 0 fsb = Vint (Int.repr 99))
&& field_at Ews t_struct_tables [StructField _FSb] fsb (gv _tables);
EX rsb : list val,
!!(Zlength rsb = 256) &&
!!(forall j, 1 <= j < i ->
(Znth (Int.unsigned (Znth j FSb)) rsb) = Vint (Int.repr j)) &&
!!(Znth 99 rsb = Vint Int.zero)
&& field_at Ews t_struct_tables [StructField _RSb] rsb (gv _tables)).
Definition gen_sbox_inv0 v_pow v_log log pow gv frozen :=
EX i: Z, gen_sbox_inv00 i v_pow v_log log pow gv frozen.
Definition gen_ftrt_inv00 i v_pow v_log log pow gv :=
PROP ( )
LOCAL (lvar _log (tarray tint 256) v_log;
lvar _pow (tarray tint 256) v_pow;
gvars gv)
SEP (data_at Tsh (tarray tint 256) pow v_pow;
data_at Tsh (tarray tint 256) log v_log;
field_at Ews t_struct_tables [StructField _FSb] (map Vint FSb) (gv _tables);
field_at Ews t_struct_tables [StructField _FT0] (partially_filled i 256 calc_FT0) (gv _tables);
field_at Ews t_struct_tables [StructField _FT1] (partially_filled i 256 calc_FT1) (gv _tables);
field_at Ews t_struct_tables [StructField _FT2] (partially_filled i 256 calc_FT2) (gv _tables);
field_at Ews t_struct_tables [StructField _FT3] (partially_filled i 256 calc_FT3) (gv _tables);
field_at Ews t_struct_tables [StructField _RSb] (map Vint RSb) (gv _tables);
field_at Ews t_struct_tables [StructField _RT0] (partially_filled i 256 calc_RT0) (gv _tables);
field_at Ews t_struct_tables [StructField _RT1] (partially_filled i 256 calc_RT1) (gv _tables);
field_at Ews t_struct_tables [StructField _RT2] (partially_filled i 256 calc_RT2) (gv _tables);
field_at Ews t_struct_tables [StructField _RT3] (partially_filled i 256 calc_RT3) (gv _tables);
field_at Ews t_struct_tables [StructField _RCON] (map Vint RCON) (gv _tables)).
Definition gen_ftrt_inv0 v_pow v_log log pow gv :=
EX i: Z, gen_ftrt_inv00 i v_pow v_log log pow gv.

Lemma add_no_overflow: forall n i log
(Hn: 1 <= n < 256)
(Hlog : forall j : Z, 1 <= j < 256 -> Znth j log = log3 (Int.repr j))
(H1: forall i : Z, Int.unsigned (Znth i RSb) <= Byte.max_unsigned)
(H3 : (if Int.eq (Znth i RSb) Int.zero
then Int.zero else Int.one) <> Int.zero),
Int.min_signed <=
Int.signed (Int.repr (Znth n log)) +
Int.signed (Int.repr (Znth (Int.unsigned (Znth i RSb)) log))
<= Int.max_signed.