val clientKeyExchange_parser32 (k:keyExchangeAlgorithm): LS.parser32 (clientKeyExchange_parser k)
val clientKeyExchange_parser32 (k:keyExchangeAlgorithm): LS.parser32 (clientKeyExchange_parser k)
let clientKeyExchange_parser32 k =
  LS.parse32_sum_cases clientKeyExchange_sum parse_clientKeyExchange_cases parse32_clientKeyExchange_cases (_ by (LP.dep_enum_destr_tac ())) (keyExchangeAlgorithm_as_enum_key k)
module MiTLS.Parsers.ClientKeyExchange

(* 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.KeyExchangeAlgorithm

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

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

inline_for_extraction let key_of_clientKeyExchange (x:clientKeyExchange') : LP.enum_key keyExchangeAlgorithm_enum =
  match x with
  | Cke_rsa _ -> keyExchangeAlgorithm_as_enum_key Rsa
  | Cke_dhe _ -> keyExchangeAlgorithm_as_enum_key Dhe
  | Cke_ecdhe _ -> keyExchangeAlgorithm_as_enum_key Ecdhe
  | Cke_dh_anon _ -> keyExchangeAlgorithm_as_enum_key Dh_anon

inline_for_extraction let clientKeyExchange_case_of_keyExchangeAlgorithm (x:keyExchangeAlgorithm) : Type0 =
  match x with
  | Rsa -> encryptedPreMasterSecret
  | Dhe -> clientDiffieHellmanPublic
  | Ecdhe -> clientECDiffieHellmanPublic
  | Dh_anon -> clientDiffieHellmanPublic

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

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

inline_for_extraction let synth_clientKeyExchange_cases (x:LP.enum_key keyExchangeAlgorithm_enum) (y:clientKeyExchange_case_of_keyExchangeAlgorithm x)
  : LP.refine_with_tag key_of_clientKeyExchange x =
  match x with
  | Rsa -> clientKeyExchange_refine x (Cke_rsa (to_clientKeyExchange_case_of_keyExchangeAlgorithm Rsa y))
  | Dhe -> clientKeyExchange_refine x (Cke_dhe (to_clientKeyExchange_case_of_keyExchangeAlgorithm Dhe y))
  | Ecdhe -> clientKeyExchange_refine x (Cke_ecdhe (to_clientKeyExchange_case_of_keyExchangeAlgorithm Ecdhe y))
  | Dh_anon -> clientKeyExchange_refine x (Cke_dh_anon (to_clientKeyExchange_case_of_keyExchangeAlgorithm Dh_anon y))

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

let synth_clientKeyExchange_cases_recip_pre (k:LP.enum_key keyExchangeAlgorithm_enum)
  (x:LP.refine_with_tag key_of_clientKeyExchange k) : GTot bool =
  match k with
  | Rsa -> Cke_rsa? x
  | Dhe -> Cke_dhe? x
  | Ecdhe -> Cke_ecdhe? x
  | Dh_anon -> Cke_dh_anon? x

let synth_clientKeyExchange_cases_recip_pre_intro (k:LP.enum_key keyExchangeAlgorithm_enum) (x:LP.refine_with_tag key_of_clientKeyExchange k)
  : Lemma (synth_clientKeyExchange_cases_recip_pre k x == true) =
  norm_spec [delta; iota] (synth_clientKeyExchange_cases_recip_pre k x)

inline_for_extraction let synth_clientKeyExchange_cases_recip (k:LP.enum_key keyExchangeAlgorithm_enum)
  (x:LP.refine_with_tag key_of_clientKeyExchange k) : (clientKeyExchange_case_of_keyExchangeAlgorithm k) =
  match k with
  | Rsa -> [@inline_let] let _ = synth_clientKeyExchange_cases_recip_pre_intro Rsa x in
    (match x with Cke_rsa y -> (from_clientKeyExchange_case_of_keyExchangeAlgorithm Rsa y))
  | Dhe -> [@inline_let] let _ = synth_clientKeyExchange_cases_recip_pre_intro Dhe x in
    (match x with Cke_dhe y -> (from_clientKeyExchange_case_of_keyExchangeAlgorithm Dhe y))
  | Ecdhe -> [@inline_let] let _ = synth_clientKeyExchange_cases_recip_pre_intro Ecdhe x in
    (match x with Cke_ecdhe y -> (from_clientKeyExchange_case_of_keyExchangeAlgorithm Ecdhe y))
  | Dh_anon -> [@inline_let] let _ = synth_clientKeyExchange_cases_recip_pre_intro Dh_anon x in
    (match x with Cke_dh_anon y -> (from_clientKeyExchange_case_of_keyExchangeAlgorithm Dh_anon y))

inline_for_extraction let clientKeyExchange_sum = LP.make_sum' keyExchangeAlgorithm_enum key_of_clientKeyExchange
  clientKeyExchange_case_of_keyExchangeAlgorithm synth_clientKeyExchange_cases synth_clientKeyExchange_cases_recip
  (_ by (LP.make_sum_synth_case_recip_synth_case_tac ()))
  (_ by (LP.synth_case_synth_case_recip_tac ()))

noextract let parse_clientKeyExchange_cases (x:LP.sum_key clientKeyExchange_sum)
  : k:LP.parser_kind & LP.parser k (clientKeyExchange_case_of_keyExchangeAlgorithm x) =
  match x with
  | Rsa -> [@inline_let] let u : (k: LP.parser_kind & LP.parser k (clientKeyExchange_case_of_keyExchangeAlgorithm Rsa)) = (| _, encryptedPreMasterSecret_parser |) in u
  | Dhe -> [@inline_let] let u : (k: LP.parser_kind & LP.parser k (clientKeyExchange_case_of_keyExchangeAlgorithm Dhe)) = (| _, clientDiffieHellmanPublic_parser |) in u
  | Ecdhe -> [@inline_let] let u : (k: LP.parser_kind & LP.parser k (clientKeyExchange_case_of_keyExchangeAlgorithm Ecdhe)) = (| _, clientECDiffieHellmanPublic_parser |) in u
  | Dh_anon -> [@inline_let] let u : (k: LP.parser_kind & LP.parser k (clientKeyExchange_case_of_keyExchangeAlgorithm Dh_anon)) = (| _, clientDiffieHellmanPublic_parser |) in u
  | _ -> (| _, LP.parse_false |)

noextract let serialize_clientKeyExchange_cases (x:LP.sum_key clientKeyExchange_sum)
  : LP.serializer (dsnd (parse_clientKeyExchange_cases x)) =
  match x with
  | Rsa -> [@inline_let] let u : LP.serializer (dsnd (parse_clientKeyExchange_cases Rsa)) = encryptedPreMasterSecret_serializer in u
  | Dhe -> [@inline_let] let u : LP.serializer (dsnd (parse_clientKeyExchange_cases Dhe)) = clientDiffieHellmanPublic_serializer in u
  | Ecdhe -> [@inline_let] let u : LP.serializer (dsnd (parse_clientKeyExchange_cases Ecdhe)) = clientECDiffieHellmanPublic_serializer in u
  | Dh_anon -> [@inline_let] let u : LP.serializer (dsnd (parse_clientKeyExchange_cases Dh_anon)) = clientDiffieHellmanPublic_serializer in u
  | _ -> LP.serialize_false

inline_for_extraction noextract let parse32_clientKeyExchange_cases (x:LP.sum_key clientKeyExchange_sum)
  : LS.parser32 (dsnd (parse_clientKeyExchange_cases x)) =
  match x with
  | Rsa -> [@inline_let] let u : LS.parser32 (dsnd (parse_clientKeyExchange_cases Rsa)) = encryptedPreMasterSecret_parser32 in u
  | Dhe -> [@inline_let] let u : LS.parser32 (dsnd (parse_clientKeyExchange_cases Dhe)) = clientDiffieHellmanPublic_parser32 in u
  | Ecdhe -> [@inline_let] let u : LS.parser32 (dsnd (parse_clientKeyExchange_cases Ecdhe)) = clientECDiffieHellmanPublic_parser32 in u
  | Dh_anon -> [@inline_let] let u : LS.parser32 (dsnd (parse_clientKeyExchange_cases Dh_anon)) = clientDiffieHellmanPublic_parser32 in u
  | _ -> LS.parse32_false

inline_for_extraction noextract let serialize32_clientKeyExchange_cases (x:LP.sum_key clientKeyExchange_sum)
  : LS.serializer32 (serialize_clientKeyExchange_cases x) =
  match x with
  | Rsa -> [@inline_let] let u : LS.serializer32 (serialize_clientKeyExchange_cases Rsa) = encryptedPreMasterSecret_serializer32 in u
  | Dhe -> [@inline_let] let u : LS.serializer32 (serialize_clientKeyExchange_cases Dhe) = clientDiffieHellmanPublic_serializer32 in u
  | Ecdhe -> [@inline_let] let u : LS.serializer32 (serialize_clientKeyExchange_cases Ecdhe) = clientECDiffieHellmanPublic_serializer32 in u
  | Dh_anon -> [@inline_let] let u : LS.serializer32 (serialize_clientKeyExchange_cases Dh_anon) = clientDiffieHellmanPublic_serializer32 in u
  | _ -> LS.serialize32_false

inline_for_extraction noextract let size32_clientKeyExchange_cases (x:LP.sum_key clientKeyExchange_sum)
  : LSZ.size32 (serialize_clientKeyExchange_cases x) =
  match x with
  | Rsa -> [@inline_let] let u : LSZ.size32 (serialize_clientKeyExchange_cases Rsa) = encryptedPreMasterSecret_size32 in u
  | Dhe -> [@inline_let] let u : LSZ.size32 (serialize_clientKeyExchange_cases Dhe) = clientDiffieHellmanPublic_size32 in u
  | Ecdhe -> [@inline_let] let u : LSZ.size32 (serialize_clientKeyExchange_cases Ecdhe) = clientECDiffieHellmanPublic_size32 in u
  | Dh_anon -> [@inline_let] let u : LSZ.size32 (serialize_clientKeyExchange_cases Dh_anon) = clientDiffieHellmanPublic_size32 in u
  | _ -> LSZ.size32_false

inline_for_extraction noextract let validate_clientKeyExchange_cases (x:LP.sum_key clientKeyExchange_sum)
  : LL.validator (dsnd (parse_clientKeyExchange_cases x)) =
  match x with
  | Rsa -> [@inline_let] let u : LL.validator (dsnd (parse_clientKeyExchange_cases Rsa)) = encryptedPreMasterSecret_validator in u
  | Dhe -> [@inline_let] let u : LL.validator (dsnd (parse_clientKeyExchange_cases Dhe)) = clientDiffieHellmanPublic_validator in u
  | Ecdhe -> [@inline_let] let u : LL.validator (dsnd (parse_clientKeyExchange_cases Ecdhe)) = clientECDiffieHellmanPublic_validator in u
  | Dh_anon -> [@inline_let] let u : LL.validator (dsnd (parse_clientKeyExchange_cases Dh_anon)) = clientDiffieHellmanPublic_validator in u
  | _ -> LL.validate_false ()

inline_for_extraction noextract let jump_clientKeyExchange_cases (x:LP.sum_key clientKeyExchange_sum)
  : LL.jumper (dsnd (parse_clientKeyExchange_cases x)) =
  match x with
  | Rsa -> [@inline_let] let u : LL.jumper (dsnd (parse_clientKeyExchange_cases Rsa)) = encryptedPreMasterSecret_jumper in u
  | Dhe -> [@inline_let] let u : LL.jumper (dsnd (parse_clientKeyExchange_cases Dhe)) = clientDiffieHellmanPublic_jumper in u
  | Ecdhe -> [@inline_let] let u : LL.jumper (dsnd (parse_clientKeyExchange_cases Ecdhe)) = clientECDiffieHellmanPublic_jumper in u
  | Dh_anon -> [@inline_let] let u : LL.jumper (dsnd (parse_clientKeyExchange_cases Dh_anon)) = clientDiffieHellmanPublic_jumper in u
  | _ -> LL.jump_false

let _ : squash (clientKeyExchange_parser_kind == LP.weaken_parse_cases_kind clientKeyExchange_sum parse_clientKeyExchange_cases) =
  _ by (FStar.Tactics.norm [delta; iota; primops]; FStar.Tactics.trefl ())

let clientKeyExchange_eq_lemma (k:keyExchangeAlgorithm) : Lemma (clientKeyExchange k == LP.sum_cases clientKeyExchange_sum (keyExchangeAlgorithm_as_enum_key k)) [SMTPat (clientKeyExchange k)] =
  match k with
  | Rsa -> assert_norm (clientKeyExchange Rsa == LP.sum_cases clientKeyExchange_sum (keyExchangeAlgorithm_as_enum_key Rsa))
  | Dhe -> assert_norm (clientKeyExchange Dhe == LP.sum_cases clientKeyExchange_sum (keyExchangeAlgorithm_as_enum_key Dhe))
  | Ecdhe -> assert_norm (clientKeyExchange Ecdhe == LP.sum_cases clientKeyExchange_sum (keyExchangeAlgorithm_as_enum_key Ecdhe))
  | Dh_anon -> assert_norm (clientKeyExchange Dh_anon == LP.sum_cases clientKeyExchange_sum (keyExchangeAlgorithm_as_enum_key Dh_anon))

let clientKeyExchange_parser k =
  LP.parse_sum_cases clientKeyExchange_sum parse_clientKeyExchange_cases (keyExchangeAlgorithm_as_enum_key k)

let clientKeyExchange_serializer k =
  LP.serialize_sum_cases clientKeyExchange_sum parse_clientKeyExchange_cases serialize_clientKeyExchange_cases (keyExchangeAlgorithm_as_enum_key k)

let clientKeyExchange_bytesize (k:keyExchangeAlgorithm) (x:clientKeyExchange k) : GTot nat = let s = (clientKeyExchange_serializer k) in Seq.length (s x)

let clientKeyExchange_bytesize_eq k x = ()
/
prims.fst.checked MiTLS.Parsers.KeyExchangeAlgorithm.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.ClientKeyExchange.fst
k: MiTLS.Parsers.KeyExchangeAlgorithm.keyExchangeAlgorithm
  -> LowParse.SLow.Base.parser32 (MiTLS.Parsers.ClientKeyExchange.clientKeyExchange_parser k)
MiTLS.Parsers.KeyExchangeAlgorithm.keyExchangeAlgorithm LowParse.SLow.Sum.parse32_sum_cases MiTLS.Parsers.ClientKeyExchange.clientKeyExchange_sum MiTLS.Parsers.ClientKeyExchange.parse_clientKeyExchange_cases MiTLS.Parsers.ClientKeyExchange.parse32_clientKeyExchange_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.SLow.Sum.parse32_sum_cases_t LowParse.Spec.Enum.enum_tail LowParse.Spec.Enum.enum_key LowParse.Spec.Enum.dep_enum_destr_cons_nil MiTLS.Parsers.ClientKeyExchange.keyExchangeAlgorithm_as_enum_key LowParse.SLow.Base.parser32 MiTLS.Parsers.ClientKeyExchange.clientKeyExchange_parser_kind MiTLS.Parsers.ClientKeyExchange.clientKeyExchange MiTLS.Parsers.ClientKeyExchange.clientKeyExchange_parser
let clientKeyExchange_parser32 k =
  
LS.parse32_sum_cases clientKeyExchange_sum
  parse_clientKeyExchange_cases
  parse32_clientKeyExchange_cases
  (FStar.Tactics.Effect.synth_by_tactic (fun _ -> (LP.dep_enum_destr_tac ())))
  (keyExchangeAlgorithm_as_enum_key k)