val finished_validator (k:digestSize): LL.validator (finished_parser k)
val finished_validator (k:digestSize): LL.validator (finished_parser k)
let finished_validator k =
  LL.validate_sum_cases finished_sum parse_finished_cases validate_finished_cases (_ by (LP.dep_enum_destr_tac ())) (digestSize_as_enum_key k)
module MiTLS.Parsers.Finished

(* This file has been automatically generated by EverParse. *)
open FStar.Bytes
module U8 = FStar.UInt8
module U16 = FStar.UInt16
module U32 = FStar.UInt32
module U64 = FStar.UInt64
module LP = LowParse.Spec
module LT = LowParse.TacLib
module LS = LowParse.SLow
module LSZ = LowParse.SLow
module LPI = LowParse.Spec.AllIntegers
module LL = LowParse.Low
module L = FStar.List.Tot
module B = LowStar.Buffer
module BY = FStar.Bytes
module HS = FStar.HyperStack
module HST = FStar.HyperStack.ST

#reset-options "--using_facts_from '* -FStar.Tactics -FStar.Reflection' --z3rlimit 16 --z3cliopt smt.arith.nl=false --max_fuel 2 --max_ifuel 2"

friend MiTLS.Parsers.DigestSize

// Need high Z3 limits for large sum types
#set-options "--z3rlimit 180"

inline_for_extraction unfold let digestSize_as_enum_key (x:digestSize) : Pure (LP.enum_key digestSize_enum)
  (requires norm [delta; zeta; iota; primops] (LP.list_mem x (LP.list_map fst digestSize_enum)) == true) (ensures fun _ -> True) =
  [@inline_let] let _ = norm_spec [delta; zeta; iota; primops] (LP.list_mem x (LP.list_map fst digestSize_enum)) in x

inline_for_extraction let key_of_finished (x:finished') : LP.enum_key digestSize_enum =
  match x with
  | Verify_data_hash_32 _ -> digestSize_as_enum_key Hash_32
  | Verify_data_hash_48 _ -> digestSize_as_enum_key Hash_48
  | Verify_data_hash_64 _ -> digestSize_as_enum_key Hash_64

inline_for_extraction let finished_case_of_digestSize (x:digestSize) : Type0 =
  match x with
  | Hash_32 -> finished32
  | Hash_48 -> finished48
  | Hash_64 -> finished64

unfold inline_for_extraction let to_finished_case_of_digestSize (x:digestSize) (#x':digestSize) (y:finished_case_of_digestSize x')  : Pure (norm [delta_only [(`%finished_case_of_digestSize)]; iota] (finished_case_of_digestSize x))
  (requires (x == x')) (ensures (fun y' -> y' == y)) =
  [@inline_let] let _ = norm_spec [delta_only [(`%finished_case_of_digestSize)] ; iota] (finished_case_of_digestSize x) in y

unfold inline_for_extraction let finished_refine (k:LP.enum_key digestSize_enum) (x:finished')
  : Pure (LP.refine_with_tag key_of_finished k)  (requires norm [delta; iota; zeta] (key_of_finished x) == k) (ensures (fun y -> y == x)) =
  [@inline_let] let _ = norm_spec [delta; iota; zeta] (key_of_finished x) in x

inline_for_extraction let synth_finished_cases (x:LP.enum_key digestSize_enum) (y:finished_case_of_digestSize x)
  : LP.refine_with_tag key_of_finished x =
  match x with
  | Hash_32 -> finished_refine x (Verify_data_hash_32 (to_finished_case_of_digestSize Hash_32 y))
  | Hash_48 -> finished_refine x (Verify_data_hash_48 (to_finished_case_of_digestSize Hash_48 y))
  | Hash_64 -> finished_refine x (Verify_data_hash_64 (to_finished_case_of_digestSize Hash_64 y))

unfold inline_for_extraction let from_finished_case_of_digestSize (#x':digestSize) (x:digestSize)
  (y: norm [delta_only [(`%finished_case_of_digestSize)]; iota] (finished_case_of_digestSize x))
  : Pure (finished_case_of_digestSize x') (requires (x == x')) (ensures (fun y' -> y' == y)) =
  [@inline_let] let _ = norm_spec [delta_only [(`%finished_case_of_digestSize)] ; iota] (finished_case_of_digestSize x) in y

let synth_finished_cases_recip_pre (k:LP.enum_key digestSize_enum)
  (x:LP.refine_with_tag key_of_finished k) : GTot bool =
  match k with
  | Hash_32 -> Verify_data_hash_32? x
  | Hash_48 -> Verify_data_hash_48? x
  | Hash_64 -> Verify_data_hash_64? x

let synth_finished_cases_recip_pre_intro (k:LP.enum_key digestSize_enum) (x:LP.refine_with_tag key_of_finished k)
  : Lemma (synth_finished_cases_recip_pre k x == true) =
  norm_spec [delta; iota] (synth_finished_cases_recip_pre k x)

inline_for_extraction let synth_finished_cases_recip (k:LP.enum_key digestSize_enum)
  (x:LP.refine_with_tag key_of_finished k) : (finished_case_of_digestSize k) =
  match k with
  | Hash_32 -> [@inline_let] let _ = synth_finished_cases_recip_pre_intro Hash_32 x in
    (match x with Verify_data_hash_32 y -> (from_finished_case_of_digestSize Hash_32 y))
  | Hash_48 -> [@inline_let] let _ = synth_finished_cases_recip_pre_intro Hash_48 x in
    (match x with Verify_data_hash_48 y -> (from_finished_case_of_digestSize Hash_48 y))
  | Hash_64 -> [@inline_let] let _ = synth_finished_cases_recip_pre_intro Hash_64 x in
    (match x with Verify_data_hash_64 y -> (from_finished_case_of_digestSize Hash_64 y))

inline_for_extraction let finished_sum = LP.make_sum' digestSize_enum key_of_finished
  finished_case_of_digestSize synth_finished_cases synth_finished_cases_recip
  (_ by (LP.make_sum_synth_case_recip_synth_case_tac ()))
  (_ by (LP.synth_case_synth_case_recip_tac ()))

noextract let parse_finished_cases (x:LP.sum_key finished_sum)
  : k:LP.parser_kind & LP.parser k (finished_case_of_digestSize x) =
  match x with
  | Hash_32 -> [@inline_let] let u : (k: LP.parser_kind & LP.parser k (finished_case_of_digestSize Hash_32)) = (| _, finished32_parser |) in u
  | Hash_48 -> [@inline_let] let u : (k: LP.parser_kind & LP.parser k (finished_case_of_digestSize Hash_48)) = (| _, finished48_parser |) in u
  | Hash_64 -> [@inline_let] let u : (k: LP.parser_kind & LP.parser k (finished_case_of_digestSize Hash_64)) = (| _, finished64_parser |) in u
  | _ -> (| _, LP.parse_false |)

noextract let serialize_finished_cases (x:LP.sum_key finished_sum)
  : LP.serializer (dsnd (parse_finished_cases x)) =
  match x with
  | Hash_32 -> [@inline_let] let u : LP.serializer (dsnd (parse_finished_cases Hash_32)) = finished32_serializer in u
  | Hash_48 -> [@inline_let] let u : LP.serializer (dsnd (parse_finished_cases Hash_48)) = finished48_serializer in u
  | Hash_64 -> [@inline_let] let u : LP.serializer (dsnd (parse_finished_cases Hash_64)) = finished64_serializer in u
  | _ -> LP.serialize_false

inline_for_extraction noextract let parse32_finished_cases (x:LP.sum_key finished_sum)
  : LS.parser32 (dsnd (parse_finished_cases x)) =
  match x with
  | Hash_32 -> [@inline_let] let u : LS.parser32 (dsnd (parse_finished_cases Hash_32)) = finished32_parser32 in u
  | Hash_48 -> [@inline_let] let u : LS.parser32 (dsnd (parse_finished_cases Hash_48)) = finished48_parser32 in u
  | Hash_64 -> [@inline_let] let u : LS.parser32 (dsnd (parse_finished_cases Hash_64)) = finished64_parser32 in u
  | _ -> LS.parse32_false

inline_for_extraction noextract let serialize32_finished_cases (x:LP.sum_key finished_sum)
  : LS.serializer32 (serialize_finished_cases x) =
  match x with
  | Hash_32 -> [@inline_let] let u : LS.serializer32 (serialize_finished_cases Hash_32) = finished32_serializer32 in u
  | Hash_48 -> [@inline_let] let u : LS.serializer32 (serialize_finished_cases Hash_48) = finished48_serializer32 in u
  | Hash_64 -> [@inline_let] let u : LS.serializer32 (serialize_finished_cases Hash_64) = finished64_serializer32 in u
  | _ -> LS.serialize32_false

inline_for_extraction noextract let size32_finished_cases (x:LP.sum_key finished_sum)
  : LSZ.size32 (serialize_finished_cases x) =
  match x with
  | Hash_32 -> [@inline_let] let u : LSZ.size32 (serialize_finished_cases Hash_32) = finished32_size32 in u
  | Hash_48 -> [@inline_let] let u : LSZ.size32 (serialize_finished_cases Hash_48) = finished48_size32 in u
  | Hash_64 -> [@inline_let] let u : LSZ.size32 (serialize_finished_cases Hash_64) = finished64_size32 in u
  | _ -> LSZ.size32_false

inline_for_extraction noextract let validate_finished_cases (x:LP.sum_key finished_sum)
  : LL.validator (dsnd (parse_finished_cases x)) =
  match x with
  | Hash_32 -> [@inline_let] let u : LL.validator (dsnd (parse_finished_cases Hash_32)) = finished32_validator in u
  | Hash_48 -> [@inline_let] let u : LL.validator (dsnd (parse_finished_cases Hash_48)) = finished48_validator in u
  | Hash_64 -> [@inline_let] let u : LL.validator (dsnd (parse_finished_cases Hash_64)) = finished64_validator in u
  | _ -> LL.validate_false ()

inline_for_extraction noextract let jump_finished_cases (x:LP.sum_key finished_sum)
  : LL.jumper (dsnd (parse_finished_cases x)) =
  match x with
  | Hash_32 -> [@inline_let] let u : LL.jumper (dsnd (parse_finished_cases Hash_32)) = finished32_jumper in u
  | Hash_48 -> [@inline_let] let u : LL.jumper (dsnd (parse_finished_cases Hash_48)) = finished48_jumper in u
  | Hash_64 -> [@inline_let] let u : LL.jumper (dsnd (parse_finished_cases Hash_64)) = finished64_jumper in u
  | _ -> LL.jump_false

let _ : squash (finished_parser_kind == LP.weaken_parse_cases_kind finished_sum parse_finished_cases) =
  _ by (FStar.Tactics.norm [delta; iota; primops]; FStar.Tactics.trefl ())

let finished_eq_lemma (k:digestSize) : Lemma (finished k == LP.sum_cases finished_sum (digestSize_as_enum_key k)) [SMTPat (finished k)] =
  match k with
  | Hash_32 -> assert_norm (finished Hash_32 == LP.sum_cases finished_sum (digestSize_as_enum_key Hash_32))
  | Hash_48 -> assert_norm (finished Hash_48 == LP.sum_cases finished_sum (digestSize_as_enum_key Hash_48))
  | Hash_64 -> assert_norm (finished Hash_64 == LP.sum_cases finished_sum (digestSize_as_enum_key Hash_64))

let finished_parser k =
  LP.parse_sum_cases finished_sum parse_finished_cases (digestSize_as_enum_key k)

let finished_serializer k =
  LP.serialize_sum_cases finished_sum parse_finished_cases serialize_finished_cases (digestSize_as_enum_key k)

let finished_bytesize (k:digestSize) (x:finished k) : GTot nat = let s = (finished_serializer k) in Seq.length (s x)

let finished_bytesize_eq k x = ()

let finished_parser32 k =
  LS.parse32_sum_cases finished_sum parse_finished_cases parse32_finished_cases (_ by (LP.dep_enum_destr_tac ())) (digestSize_as_enum_key k)

let finished_serializer32 k =
  LS.serialize32_sum_cases finished_sum serialize_finished_cases serialize32_finished_cases (_ by (LP.dep_enum_destr_tac ())) (digestSize_as_enum_key k)

let finished_size32 k =
  LSZ.size32_sum_cases finished_sum serialize_finished_cases size32_finished_cases (_ by (LP.dep_enum_destr_tac ())) (digestSize_as_enum_key k)
/
prims.fst.checked MiTLS.Parsers.DigestSize.fst.checked LowStar.Buffer.fst.checked LowParse.TacLib.fst.checked LowParse.Spec.AllIntegers.fst.checked LowParse.Spec.fst.checked LowParse.SLow.fst.checked LowParse.Low.fst.checked FStar.UInt8.fsti.checked FStar.UInt64.fsti.checked FStar.UInt32.fsti.checked FStar.UInt16.fsti.checked FStar.Tactics.Effect.fsti.checked FStar.Tactics.fst.checked FStar.Seq.fst.checked FStar.Pervasives.fsti.checked FStar.List.Tot.fst.checked FStar.HyperStack.ST.fsti.checked FStar.HyperStack.fst.checked FStar.Bytes.fsti.checked
MiTLS.Parsers.Finished.fst
k: MiTLS.Parsers.DigestSize.digestSize
  -> LowParse.Low.Base.validator (MiTLS.Parsers.Finished.finished_parser k)
MiTLS.Parsers.DigestSize.digestSize LowParse.Low.Sum.validate_sum_cases MiTLS.Parsers.Finished.finished_sum MiTLS.Parsers.Finished.parse_finished_cases MiTLS.Parsers.Finished.validate_finished_cases LowParse.Spec.Enum.dep_enum_destr_cons LowParse.Spec.Sum.sum_key_type LowParse.Spec.Sum.sum_repr_type LowParse.Spec.Sum.sum_enum LowParse.Low.Sum.validate_sum_cases_t LowParse.Spec.Enum.enum_tail LowParse.Spec.Enum.enum_key LowParse.Spec.Enum.dep_enum_destr_cons_nil MiTLS.Parsers.Finished.digestSize_as_enum_key LowParse.Low.Base.validator MiTLS.Parsers.Finished.finished_parser_kind MiTLS.Parsers.Finished.finished MiTLS.Parsers.Finished.finished_parser
let finished_validator k =
  
LL.validate_sum_cases finished_sum
  parse_finished_cases
  validate_finished_cases
  (FStar.Tactics.Effect.synth_by_tactic (fun _ -> (LP.dep_enum_destr_tac ())))
  (digestSize_as_enum_key k)