# `Pasexto.Paserk`
[🔗](https://github.com/alexkornitzer/pasexto/blob/v0.1.2/lib/pasexto/paserk.ex#L1)

PASERK is an extension to PASETO that provides key-wrapping and serialization.

PASERK supports the following purposes:

  * `lid` - Unique Identifier for a separate PASERK for local PASETOs.

  * `local` - Symmetric key for local tokens.

  * `local_pw` - Symmetric key wrapped using password-based encryption.

  * `local_wrap` - Symmetric key wrapped by another symmetric key.

  * `pid` - Unique Identifier for a separate PASERK for public PASETOs.

  * `public` - Public key for verifying public tokens.

  * `seal` - Symmetric key wrapped using asymmetric encryption.

  * `secret` - Secret key for signing public tokens.

  * `secret_pw` - Asymmetric secret key wrapped using password-based encryption.

  * `secret_wrap` - Asymmetric secret key wrapped by another symmetric key.

  * `sid` - Unique Identifier for a separate PASERK for public PASETOs.

A PASERK can be created like so:

```elixir
iex> key = Pasexto.Key.new(:v4, :local)
iex> {:ok, paserk} = Pasexto.Paserk.build(:k4, :lid, key)
```

# `kind`

```elixir
@type kind() :: :k1 | :k2 | :k3 | :k4
```

# `purpose`

```elixir
@type purpose() ::
  :lid
  | :local
  | :local_pw
  | :local_wrap
  | :pid
  | :public
  | :seal
  | :secret
  | :secret_pw
  | :secret_wrap
  | :sid
```

# `build`

```elixir
@spec build(kind(), purpose(), Pasexto.Key.t(), keyword()) ::
  {:ok, binary()} | {:error, term()}
```

Returns a PASERK for the given kind, purpose and key.

Some purposes require additional information to successfully build, these can
be provided as options.

## Options

* `password` - A password for use with `:local_pw` and `:secret_pw`.

* `public_key` - A public key for use with `:seal`.
  * for `v1` this must be a 4096-bit RSA public key.
  * for `v2` this must be a Ed25519 public key.
  * for `v3` this must be a P-384 public key.
  * for `v4` this must be a Ed25519 public key.

* `wrapper` - A `Pasexto.Wrapper` for use with `:local_wrap` and
  `:secret_wrap`.

In addition to the above options `:local_pw` and `:secret_pw` also accept the
following options for their key derivation functions:

* `iterations` - defines how many iterations to perform, defaults to
  `100_000`. Versions `v1` and `v3` only.

* `memory_cost` - defines how much memory to use in bytes, defaults to
  `67_108_864`. Versions `v2` and `v4` only.

* `parallelism_degree` - defines the independent number of tasks, defaults to
  `1`. Versions `v2` and `v4` only.

* `time_cost` - defines the execution time as a number of iterations,
  defaults to `2`. Versions `v2` and `v4` only.

# `parse`

```elixir
@spec parse(kind(), purpose(), binary(), keyword()) ::
  {:ok, binary()} | {:error, term()}
```

Parses a PASERK for the given kind and purpose.

Some purposes require additional information to successfully build, these can
be provided as options.

## Options

* `password` - A password for use with `:local_pw` and `:secret_pw`.

* `private_key` - A private key for use with `:seal`.
  * for `v1` this must be a 4096-bit RSA private key.
  * for `v2` this must be a Ed25519 private key.
  * for `v3` this must be a P-384 private key.
  * for `v4` this must be a Ed25519 private key.

* `wrapper` - A `Pasexto.Wrapper` for use with `:local_wrap` and `:secret_wrap`.

As `:lid`, `:pid` and `:sid` can only be serialised, trying to set this
purpose will raise an argument error.

---

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