Fixpoint upd_upto (x: SixteenByte * SixteenByte * (SixteenByte * SixteenByte)) i (l:list val):list val :=
  match i with
    O => l
  | S n =>
     match x with (Nonce, C, (Key1, Key2)) =>
     ((upd_Znth (11 + (Z.of_nat n))
     (upd_Znth(6 + (Z.of_nat n))
        (upd_Znth (1 + (Z.of_nat n))
           (upd_Znth (5 * (Z.of_nat n)) (upd_upto x n l)
              (Vint (littleendian (Select16Q C (Z.of_nat n)))))
           (Vint (littleendian (Select16Q Key1 (Z.of_nat n)))))
        (Vint (littleendian (Select16Q Nonce (Z.of_nat n)))))
     (Vint (littleendian (Select16Q Key2 (Z.of_nat n))))))
     end
  end.

(* Specifications: *)
Lemma upd_upto_Sn Nonce C Key1 Key2 n l: upd_upto (Nonce, C, (Key1, Key2)) (S n) l = ((upd_Znth (11 + (Z.of_nat n)) (upd_Znth (6 + (Z.of_nat n)) (upd_Znth (1 + (Z.of_nat n)) (upd_Znth (5 * (Z.of_nat n)) (upd_upto (Nonce, C, (Key1, Key2)) n l) (Vint (littleendian (Select16Q C (Z.of_nat n))))) (Vint (littleendian (Select16Q Key1 (Z.of_nat n))))) (Vint (littleendian (Select16Q Nonce (Z.of_nat n))))) (Vint (littleendian (Select16Q Key2 (Z.of_nat n)))))).
Lemma upd_upto_Zlength data l (H: Zlength l = 16): forall i (I:(0<=i<=4)%nat), Zlength (upd_upto data i l) = 16.
Lemma upd_upto_Vint data: forall n, 0<=n<16 -> exists i, Znth n (upd_upto data 4 (list_repeat 16 Vundef)) = Vint i.
Lemma upd_upto_char data l: Zlength l = 16 -> upd_upto data 4 l = match data with ((Nonce, C), (Key1, Key2)) => match Nonce with (N1, N2, N3, N4) => match C with (C1, C2, C3, C4) => match Key1 with (K1, K2, K3, K4) => match Key2 with (L1, L2, L3, L4) => map Vint (map littleendian [C1; K1; K2; K3; K4; C2; N1; N2; N3; N4; C3; L1; L2; L3; L4; C4]) end end end end end.