Local Open Scope logic.
Fixpoint HMAC_DRBG_update_round (HMAC: list byte -> list byte -> list byte) (provided_data K V: list byte) (round: nat): (list byte * list byte) :=
match round with
| O => (K, V)
| S round' =>
let (K, V) := HMAC_DRBG_update_round HMAC provided_data K V round' in
let K := HMAC (V ++ [Byte.repr (Z.of_nat round')] ++ provided_data) K in
let V := HMAC V K in
(K, V)
end.
Definition HMAC_DRBG_update_concrete (HMAC: list byte -> list byte -> list byte) (provided_data K V: list byte): (list byte * list byte) :=
let rounds := match provided_data with
| [] => 1%nat
| _ => 2%nat
end in
HMAC_DRBG_update_round HMAC provided_data K V rounds.
Definition update_rounds (non_empty_additional: bool): Z :=
if non_empty_additional then 2 else 1.

Lemma update_char add_len contents (HL:add_len = Zlength contents \/ add_len = 0)
(key1 V0 : list byte) additional reseed_counter entropy_len prediction_resistance V key0
reseed_interval
(H : (key1, V0) =
HMAC_DRBG_update_round HMAC256 (contents_with_add additional add_len contents) key0 V
(Z.to_nat
(if
(negb (Memory.EqDec_val additional nullval) &&
negb (initial_world.EqDec_Z add_len 0))%bool
then 2
else 1))):
hmac256drbgabs_hmac_drbg_update
(HMAC256DRBGabs key0 V reseed_counter entropy_len prediction_resistance
reseed_interval) (contents_with_add additional add_len contents) =
HMAC256DRBGabs key1 V0 reseed_counter entropy_len prediction_resistance
reseed_interval.