(*Require Import FCF.HMAC_DRBG_definitions_only.*)
(*Variant of FCF.HMAC_DRBG_definitions_only.Gen_loop that - specializes eta to 256 - specializes f to HMAC256 - replaces v'::bits with bits++[v']*)
Fixpoint Gen_loop_Bvec (k : Bvector 256) (v : Bvector 256) (n : nat)
: list (Bvector 256) * Bvector 256 :=
match n with
| O => (nil, v)
| S n' =>
let v' := HMAC_Bvec k (to_list v) in
let (bits, v'') := Gen_loop_Bvec k v' n' in
(List.app bits (List.cons v' List.nil), v'')
end.
(*Variant of Gen_loop_bvec that uses Blist instead of Bvector 256*)
Fixpoint Gen_loop_Blist (k : Blist) (v : Blist) (n : nat)
: list Blist * Blist :=
match n with
| O => (nil, v)
| S n' =>
let v' := HMAC_Blist k v in
let (bits, v'') := Gen_loop_Blist k v' n' in
(List.app bits (List.cons v' List.nil), v'')
end.
(*Variant of Gen_loop_bvec that uses list byte instead of Bvector 256*)
Fixpoint Gen_loop_Zlist (k : list byte) (v : list byte) (n : nat)
: list (list byte) * (list byte) :=
match n with
| O => (nil, v)
| S n' =>
let v' := HMAC256 v k in
let (bits, v'') := Gen_loop_Zlist k v' n' in
(List.app bits (List.cons v' List.nil), v'')
end.
Definition Equiv n:= forall k v blocks u
(G: Gen_loop_Zlist k v n = (blocks, u)) m
(M: 32*(Z.of_nat n-1) < m <=32*(Z.of_nat n)),
HMAC_DRBG_generate_helper_Z HMAC256 k v m = (u,flatten (rev blocks)).
*)
(*Hence, by induction the following equivalence property holds*)
Definition GenUpdate_original_Blist (state : Blist * Blist) (n : nat) :
(list Blist * (Blist * Blist)) :=
match state with (k, v) =>
match Gen_loop_Blist k v n with (bits, v') =>
let k' := HMAC_Blist k (v' ++ zeroes)%list in
let v'' := HMAC_Blist k' v' in (bits, (k', v''))
end
end.
Definition GenUpdate_original_Zlist (state : list byte * list byte) (n : nat) :
(list (list byte) * (list byte * list byte)) :=
match state with (k, v) =>
match Gen_loop_Zlist k v n with (blocks, v') =>
let k' := HMAC256 (v' ++ [Byte.zero]) k in
let v'' := HMAC256 v' k' in (blocks, (k', v''))
end
end.
(*Specialization of HMAC256_DRBG_generate_algorithm: no additional input*)
Definition FunGenerate RI (WS: DRBG_functions.DRBG_working_state) n: DRBG_functions.DRBG_generate_algorithm_result :=
HMAC256_DRBG_functional_prog.HMAC256_DRBG_generate_algorithm RI
WS
n
nil.
Opaque mult.
Opaque FunGenerate.
(*The function occurring in the VST spec of mbedtls' random function ie no additional input*)
Definition mbedtls_generate s I n :=
match mbedtls_HMAC256_DRBG_generate_function s I n []
with ENTROPY.success (bytes, J) ss =>
match J with ((((VV, KK), RC), _), PR) =>
Some (bytes, ss, HMAC256DRBGabs KK VV RC (hmac256drbgabs_entropy_len I) PR
(hmac256drbgabs_reseed_interval I))
end
| _ => None
end.

Lemma mbedtls_generate_Bridge s I (n:nat) bytes F ss (M: mbedtls_generate s I (32 * Z.of_nat n) = Some(bytes, ss, F)) (N:(0 < n)%nat):
match I with HMAC256DRBGabs k v reseed_counter entropy_len prediction_resistance reseed_interval =>
reseed_counter <= reseed_interval -> prediction_resistance = false ->
forall (KL: Datatypes.length (bytesToBits k) = 256%nat) (VL:Datatypes.length (bytesToBits v) = 256%nat),
match F with HMAC256DRBGabs KK VV rc _ _ _ =>
s=ss /\ rc=reseed_counter+1 /\
match GenUpdate_original_core (Blist.of_list_length _ KL, Blist.of_list_length _ VL) n with (blocks, kv) =>
bitsToBytes (@Vector.to_list _ 256 (fst kv)) = KK /\
bitsToBytes (@Vector.to_list _ 256 (snd kv)) = VV /\
bytes = (bitsToBytes (Fold.flatten (map (@Vector.to_list _ 256) blocks)))
end
end end.