# `SSL.Crypto.KeySchedule`
[🔗](https://github.com/gsmlg-dev/http_fetch/blob/v0.16.7/apps/ex_ssl/lib/ssl/crypto/key_schedule.ex#L1)

Pure TLS 1.3 key-schedule derivations.

Callers supply exact transcript hashes at each protocol checkpoint. Derived
traffic states start at sequence zero for a new traffic epoch.

# `error_reason`

```elixir
@type error_reason() ::
  :unsupported_hash
  | {:unsupported_cipher_suite, term()}
  | {:invalid_input, :psk | :shared_secret | :ticket_nonce | :transcript_hash}
  | {:invalid_secret_length, atom(), pos_integer()}
  | {:invalid_input, :empty_shared_secret}
  | {:invalid_transcript_hash_length, pos_integer()}
  | {:ticket_nonce_too_long, 255}
```

# `hash`

```elixir
@type hash() :: :sha256 | :sha384
```

# `client_application_traffic_secret`

```elixir
@spec client_application_traffic_secret(hash(), binary(), binary()) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `client_handshake_traffic_secret`

```elixir
@spec client_handshake_traffic_secret(hash(), binary(), binary()) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `derived_secret`

```elixir
@spec derived_secret(hash(), binary()) :: {:ok, binary()} | {:error, error_reason()}
```

# `early_secret`

```elixir
@spec early_secret(hash(), binary() | nil) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `exporter_master_secret`

```elixir
@spec exporter_master_secret(hash(), binary(), binary()) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `finished_key`

```elixir
@spec finished_key(atom(), term()) ::
  {:ok, binary()}
  | {:error,
     :unsupported_hash | {:invalid_secret_length, :traffic_secret, 32 | 48}}
```

# `finished_verify_data`

```elixir
@spec finished_verify_data(atom(), term(), term()) ::
  {:ok, binary()}
  | {:error,
     :unsupported_hash
     | {:invalid_secret_length, :finished_key, 32 | 48}
     | {:invalid_input, :transcript_hash}
     | {:invalid_transcript_hash_length, 32 | 48}}
```

# `handshake_secret`

```elixir
@spec handshake_secret(hash(), binary(), binary()) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `master_secret`

```elixir
@spec master_secret(hash(), binary()) :: {:ok, binary()} | {:error, error_reason()}
```

# `resumption_master_secret`

```elixir
@spec resumption_master_secret(hash(), binary(), binary()) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `resumption_secret`

```elixir
@spec resumption_secret(hash(), binary(), binary()) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `server_application_traffic_secret`

```elixir
@spec server_application_traffic_secret(hash(), binary(), binary()) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `server_handshake_traffic_secret`

```elixir
@spec server_handshake_traffic_secret(hash(), binary(), binary()) ::
  {:ok, binary()} | {:error, error_reason()}
```

# `traffic_state`

```elixir
@spec traffic_state(SSL.Crypto.TrafficState.cipher_suite(), binary()) ::
  {:ok, SSL.Crypto.TrafficState.t()} | {:error, error_reason()}
```

# `traffic_update`

```elixir
@spec traffic_update(hash(), binary()) :: {:ok, binary()} | {:error, error_reason()}
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
