Local Open Scope logic.
Module Instantiate_eq.
Definition OptionalNonce: option (list byte) := None. (*The implementation takes nonce from entropy, using the el*3/2 calculation*)
(*NIST, Section 10.1: highest supported sec strength is given by the hash function's security strength for preimage resistance. For SHA256, this is (according to NIST SP 800-107, Table 1, page 11) 256 bits. See also Appendix B2 of NIST SP 800-90A. *)
Definition highest_supported_security_strength := 32. (* in bytes -- see comment for reseed*)
(*Q: should we use the sec strength of HMAC, calculated according to Section 5.3.4 of NIST SP 800-107 instead?*)
Definition requested_security_strength:= 32.  (*same as in reseed*)
Definition prediction_resistance_supported:bool:=true.
Definition mbedtls_HMAC256_DRBG_instantiate_function (entropy_stream: ENTROPY.stream)
entropy_len pr_flag (personalization_string: list byte): ENTROPY.result DRBG_state_handle :=
HMAC256_DRBG_instantiate_function entropy_len entropy_len OptionalNonce
highest_supported_security_strength max_personalization_string_length
prediction_resistance_supported entropy_stream
requested_security_strength pr_flag personalization_string.
Definition entlen:Z := 32.
Parameter Entropy_addSuccess1: forall n m s s1 l1 s2 l2,
ENTROPY.get_bytes n s = ENTROPY.success l1 s1 ->
ENTROPY.get_bytes m s1 = ENTROPY.success l2 s2 ->
ENTROPY.get_bytes (n+m) s = ENTROPY.success (l1++l2) s2.
Parameter Entropy_addSuccess2: forall n m s s1 l1 s2 e,
ENTROPY.get_bytes n s = ENTROPY.success l1 s1 ->
ENTROPY.get_bytes m s1 = ENTROPY.error e s2 ->
ENTROPY.get_bytes (n+m) s = ENTROPY.error e s2.
Parameter Entropy_addError: forall n m s s1 e, ENTROPY.get_bytes n s = ENTROPY.error e s1 ->
ENTROPY.get_bytes (n+m) s = ENTROPY.error e s1.

(* Specifications: *)
Lemma Entropy_le n s l ss: ENTROPY.success l ss = ENTROPY.get_bytes n s ->
forall m, (m <= n)%nat -> exists l' s', ENTROPY.success l' s' = ENTROPY.get_bytes m s.
Lemma Entropy_addSuccess3: forall n m s ss l,
ENTROPY.get_bytes n s = ENTROPY.success l ss -> (m <= n)%nat ->
exists l1 s1, ENTROPY.get_bytes m s = ENTROPY.success l1 s1 /\
exists l2, ENTROPY.get_bytes (n-m)%nat s1 = ENTROPY.success l2 ss /\ l=l1++l2.
Lemma instantiate_eq es prflag pers:
instantiate_function_256 es prflag pers =
mbedtls_HMAC256_DRBG_instantiate_function es entlen prflag pers.
Lemma instantiate_reseed d s pr_flag rc ri (ZLc'256F : (Zlength d >? 256) = false):
mbedtls_HMAC256_DRBG_instantiate_function s entlen pr_flag  d =
mbedtls_HMAC256_DRBG_reseed_function s (HMAC256DRBGabs initial_key initial_value rc 48 pr_flag ri) d.