repeat rewrite (Int.add_commut y0).
f_equal. f_equal. f_equal. f_equal. f_equal.
rewrite Int.add_commut.  f_equal.  f_equal. rewrite Int.add_commut. trivial.
f_equal. rewrite Int.add_commut. trivial.
Qed.
Definition zeroHex := x2i "00000000".
Goal zeroHex = Int.zero. reflexivity. Qed.
Goal quarterround (Int.zero, Int.zero, Int.zero, Int.zero) =
(Int.zero, Int.zero, Int.zero, Int.zero).
reflexivity. Qed.
Goal quarterround (map4 x2i ("d3917c5b", "55f1c407", "52a58a7a", "8f887a3b")%string) =
map4 x2i ("3e2f308c", "d90a8f36", "6ab2a923", "2883524c")%string. reflexivity. Qed.
(*MEMORYEXHAUSTION. USE VM_COMPUTE INSTEAD! Eval compute in (quarterround (Int.zero, Int.zero, Int.zero, Int.zero)).*)
Definition SixteenWord:Type := (QuadWord * QuadWord * QuadWord * QuadWord)%type.
Definition rowround(y: SixteenWord) : SixteenWord :=
match y with
((y0, y1, y2, y3), (y4, y5, y6, y7), (y8, y9, y10, y11), (y12, y13, y14, y15)) =>
match quarterround(y0, y1, y2, y3) with (z0, z1, z2, z3) =>
match quarterround(y5, y6, y7, y4) with (z5, z6, z7, z4) =>
match quarterround(y10, y11, y8, y9) with (z10, z11, z8, z9) =>
match quarterround(y15, y12, y13, y14) with (z15, z12, z13, z14) =>
((z0, z1, z2, z3), (z4, z5, z6, z7), (z8, z9, z10, z11), (z12, z13, z14, z15))
end end end end end.
Goal rowround (map4 x2i ("08521bd6", "1fe88837", "bb2aa576", "3aa26365"),
map4 x2i ("c54c6a5b", "2fc74c2f", "6dd39cc3", "da0a64f6"),
map4 x2i ("90a2f23d", "067f95a6", "06b35f61", "41e4732e"),
map4 x2i ("e859c100", "ea4d84b7", "0f619bff", "bc6e965a"))%string =
(map4 x2i ("a890d39d", "65d71596", "e9487daa", "c8ca6a86"),
map4 x2i ("949d2192", "764b7754", "e408d9b9", "7a41b4d1"),
map4 x2i ("3402e183", "3c3af432", "50669f96", "d89ef0a8"),
map4 x2i ("0040ede5", "b545fbce", "d257ed4f", "1818882d"))%string.
reflexivity. Qed.
Definition columnround(x: SixteenWord) : SixteenWord :=
match x with
((x0, x1, x2, x3), (x4, x5, x6, x7), (x8, x9, x10, x11), (x12, x13, x14, x15)) =>
match quarterround(x0, x4, x8, x12) with (y0, y4, y8, y12) =>
match quarterround(x5, x9, x13, x1) with (y5, y9, y13, y1) =>
match quarterround(x10, x14, x2, x6) with (y10, y14, y2, y6) =>
match quarterround(x15, x3, x7, x11) with (y15, y3, y7, y11) =>
((y0, y1, y2, y3), (y4, y5, y6, y7), (y8, y9, y10, y11), (y12, y13, y14, y15))
end end end end end.

(* Specifications: *)
Lemma columnround_rowround: forall x,
match columnround x with
((y0, y1, y2, y3), (y4, y5, y6, y7), (y8, y9, y10, y11), (y12, y13, y14, y15)) =>
match x with
((x0, x1, x2, x3), (x4, x5, x6, x7), (x8, x9, x10, x11), (x12, x13, x14, x15)) =>
((y0, y4, y8, y12), (y1, y5, y9, y13), (y2, y6, y10, y14), (y3, y7, y11, y15))
=
rowround ((x0, x4, x8, x12), (x1, x5, x9, x13), (x2, x6, x10, x14), (x3, x7, x11, x15))
end end.