Local Open Scope logic.
Definition load8 id ofs :=
(Sset id
(Ederef
(Ebinop Oadd
(Efield
(Ederef (Etempvar _ctx (tptr t_struct_SHA256state_st))
t_struct_SHA256state_st) _h (tarray tuint 8))
(Econst_int (Int.repr ofs) tint) (tptr tuint)) tuint)).
Definition get_h (n: Z) :=
Sset _t
(Ederef
(Ebinop Oadd
(Efield
(Ederef (Etempvar _ctx (tptr t_struct_SHA256state_st))
t_struct_SHA256state_st) _h (tarray tuint 8))
(Econst_int (Int.repr n) tint) (tptr tuint)) tuint).
Definition add_h (n: Z) (i: ident) :=
Sassign
(Ederef
(Ebinop Oadd
(Efield
(Ederef (Etempvar _ctx (tptr t_struct_SHA256state_st))
t_struct_SHA256state_st) _h (tarray tuint 8))
(Econst_int (Int.repr n) tint) (tptr tuint)) tuint)
(Ebinop Oadd (Etempvar _t tuint) (Etempvar i tuint) tuint).
Definition add_them_back :=
[get_h 0; add_h 0 _a;
get_h 1; add_h 1 _b;
get_h 2; add_h 2 _c;
get_h 3; add_h 3 _d;
get_h 4; add_h 4 _e;
get_h 5; add_h 5 _f;
get_h 6; add_h 6 _g;
get_h 7; add_h 7 _h].
Fixpoint add_upto (k: nat) (u v: list int) {struct k} :=
match k with
| O => u
| S k' => match u,v with
| u1::us, v1::vs => Int.add u1 v1 :: add_upto k' us vs
| _, _ => u
end
end.

Lemma add_s:
forall (regs atoh: list int),
Datatypes.length regs = 8%nat ->
Datatypes.length atoh = 8%nat ->
forall i i',
(i < 8)%nat ->
i' = Z.of_nat i ->
upd_Znth i' (map Vint (add_upto i regs atoh))
(Vint
(Int.add
(Znth i' (add_upto i regs atoh))
(nthi atoh i'))) =
map Vint (add_upto (S i) regs atoh).