# `Cryppo`
[🔗](https://github.com/leikind/cryppo_ex/blob/main/lib/cryppo.ex#L1)

  Main public API of Cryppo

# `encryption_strategy`

```elixir
@type encryption_strategy() :: String.t()
```

Name of an encryption or derivation strategy

Use `Cryppo.encryption_strategies/0` to get a list of encryption strategies.
Use `Cryppo.derivation_strategies/0` to get a list of derivation strategies.

# `encryption_strategy_module`

```elixir
@type encryption_strategy_module() :: atom()
```

Module of an encryption or derivation strategy

# `decrypt`

```elixir
@spec decrypt(Cryppo.EncryptedData.t(), Cryppo.EncryptionKey.t() | any()) ::
  {:ok, binary()}
  | {:error, :invalid_encryption_key}
  | :decryption_error
  | {:decryption_error, {any(), any()}}
  | {:incompatible_key,
     submitted_key_strategy: atom(), encryption_strategy: atom()}
```

Decrypt encrypted data with an encryption key

## Example

    iex> {encrypted_data, encryption_key} = Cryppo.encrypt("data to encrypt", "Aes256Gcm")
    iex> Cryppo.decrypt(encrypted_data, encryption_key)
    {:ok, "data to encrypt"}

# `decrypt_with_derived_key`

```elixir
@spec decrypt_with_derived_key(Cryppo.EncryptedDataWithDerivedKey.t(), String.t()) ::
  {:ok, binary(), Cryppo.DerivedKey.t()}
  | :decryption_error
  | {:decryption_error, {any(), any()}}
  | {:incompatible_key,
     submitted_key_strategy: atom(), encryption_strategy: atom()}
```

Decrypt data with a derived key

## Example

    iex> encrypted = Cryppo.encrypt_with_derived_key("data to encrypt", "Aes256Gcm", "Pbkdf2Hmac", "passphrase")
    iex> {:ok, decrypted, _key} = Cryppo.decrypt_with_derived_key(encrypted, "passphrase")
    iex> decrypted
    "data to encrypt"

# `derivation_strategies`

```elixir
@spec derivation_strategies() :: [encryption_strategy()]
```

List available  derivation strategies

# `encrypt`

```elixir
@spec encrypt(binary(), encryption_strategy()) ::
  Cryppo.EncryptedData.t()
  | {:unsupported_encryption_strategy, atom()}
  | :encryption_error
  | {:encryption_error, any()}
```

Generate an encryption key for an encryption strategy and encrypt data with this encryption key

## Example

    iex> {_encrypted_data, _encryption_key} = Cryppo.encrypt("data to encrypt", "Aes256Gcm")

# `encrypt`

```elixir
@spec encrypt(binary(), encryption_strategy(), Cryppo.EncryptionKey.t() | any()) ::
  Cryppo.EncryptedData.t()
  | {:unsupported_encryption_strategy, atom()}
  | {:error, :invalid_encryption_key}
  | :encryption_error
  | {:incompatible_key,
     submitted_key_strategy: atom(), encryption_strategy: atom()}
```

Encrypt data with an encryption key

## Example

    iex> encryption_key = Cryppo.generate_encryption_key("Aes256Gcm")
    iex> _encrypted_data = Cryppo.encrypt("data to encrypt", "Aes256Gcm", encryption_key)

The encryption key must match the encryption strategy:

    iex> encryption_key = Cryppo.generate_encryption_key("Aes256Gcm")
    iex> Cryppo.encrypt("data to encrypt", "Rsa4096", encryption_key)
    {:incompatible_key, [submitted_key_strategy: Cryppo.Aes256gcm, encryption_strategy: Cryppo.Rsa4096]}

# `encrypt_with_derived_key`

```elixir
@spec encrypt_with_derived_key(
  binary(),
  encryption_strategy(),
  encryption_strategy(),
  String.t()
) ::
  Cryppo.EncryptedDataWithDerivedKey.t()
  | {:unsupported_encryption_strategy, encryption_strategy()}
  | {:unsupported_key_derivation_strategy, encryption_strategy()}
```

Encrypt data with a derived key

## Example

    iex> _encrypted = Cryppo.encrypt_with_derived_key("data to encrypt", "Aes256Gcm", "Pbkdf2Hmac", "passphrase")

# `encryption_strategies`

```elixir
@spec encryption_strategies() :: [encryption_strategy()]
```

List available encryption strategies

# `generate_encryption_key`

```elixir
@spec generate_encryption_key(encryption_strategy()) ::
  Cryppo.EncryptionKey.t() | {:unsupported_encryption_strategy, binary()}
```

Generate an encryption key for an encryption strategy

The generated encrypted key is marked as belonging to the encryption strategy.

## Example

    iex> _encryption_key = Cryppo.generate_encryption_key("Aes256Gcm")

# `load`

```elixir
@spec load(binary()) ::
  {:ok,
   Cryppo.EncryptedDataWithDerivedKey.t()
   | Cryppo.EncryptedData.t()
   | Cryppo.RsaSignature.t()}
  | {:error,
     :invalid_base64
     | :invalid_bson
     | :invalid_derivation_artefacts
     | :invalid_serialization_value
     | :invalid_encryption_artefacts
     | String.t()}
  | {:unsupported_encryption_strategy, binary()}
  | {:unsupported_key_derivation_strategy, binary()}
```

Load various Cryppo data structures from their serialized forms

3 Cryppo data structures have their own serialization formats:

* `Cryppo.EncryptedData`
* `Cryppo.EncryptedDataWithDerivedKey`
* `Cryppo.RsaSignature`

## Examples

    iex> s = "Aes256Gcm.WSDb2AmsF7LFOxYb.QUAAAAACYWQABQAAAG5vbmUABWF0ABAAAAAAY9Ck6LzVGiMdiWFK6N5BawVpdgAMAAAAAG_Yxh-I0gGNYoFRigA="
    iex> {:ok, %Cryppo.EncryptedData{}} = Cryppo.load(s)

    iex> s = "Aes256Gcm.wW4M_sv_kMx14cC6.QUAAAAACYWQABQAAAG5vbmUABWF0ABAAAAAA8Aq84t28sMT9FL8cz-TmMQVpdgAMAAAAANahbwbkfWo18YuCMgA=.Pbkdf2Hmac.SzAAAAAQaQAJUwAABWl2ABQAAAAAuQTqZLVFO49lI6Kx454ffYQ9VV0QbAAgAAAAAA=="
    iex> {:ok, %Cryppo.EncryptedDataWithDerivedKey{}} = Cryppo.load(s)

    iex> s = "Sign.Rsa4096.V4JbRzpkud-3cHCGqDwGjS3TmRto5Te0iSAtD7oIzsDa83McBDYpU_eeswVZF9AGEvoAEQOCwpqJ_PgbjHKT2nHgLysK-btG6Nxk_K2J7A6Uq15X5QrOgIKTzC00dj1tzAN73u9lsRPKIfwPyp_Mlb6FNs1LoB7OvAusit6QPm8iAwHo4nOWBBUf3hO9b3gsWJ92FxnBsCLYFQj_zv4mnLHj7pDNVtq9Kp4hK6bgcIH4FZtyDKDr6bXEtlCGLDIY10UqNLylkagI36Gyafm-HnD57vRxjgHIGEsd2XcwDJ8PqqrzSYNxl-RyWD3wq0nXE_1rYJ7k1AKLM5G1Hg8B2whqcXpQ52x3zVFCAjlU9GNhT6pdUBxQYw09va7fe2w517PrwwMe90MW87fj3G7dGEKT95cDLTx1d84ybIUFUJOGKY0FF4LL0E3UqWQ92kU4bh-DSTkNmgItX34fiBIOpQDbF238IkRYyFA8LfMPfL-0_dnto9sH0E3Umi41qFvpA2Nq8r57FF4vCOSkXYWVfyitOkY_URqMLxS57azwZRBehJYDtvbqmzaYEDceeLjkxDi--Y10LT4Cz2SGiU--YDJM66PZ3Cp74gvDpsWlohcwYmMib5LrjdtvLOAtOZhoLZyGeeX0lDnwOum7lFRpJd8UIrOlTvpBo48ep2bpmgA=.VmVyaMO8dHVuZyB2ZXJib3Rlbg=="
    iex> {:ok, %Cryppo.RsaSignature{}} = Cryppo.load(s)

# `serialize`

```elixir
@spec serialize(
  Cryppo.EncryptedData.t()
  | Cryppo.EncryptedDataWithDerivedKey.t()
  | Cryppo.RsaSignature.t()
) :: binary()
```

Serialize various Cryppo data structures as a string

3 Cryppo data structures have their own serialization formats:

* `Cryppo.EncryptedData`
* `Cryppo.EncryptedDataWithDerivedKey`
* `Cryppo.RsaSignature`

## Examples

`Cryppo.EncryptedData`:

    iex> {encrypted_data, _key} = Cryppo.encrypt("data to encrypt", "Aes256Gcm")
    iex> Cryppo.serialize(encrypted_data)

`Cryppo.EncryptedDataWithDerivedKey`:

    iex> "data to encrypt"
    ...> |> Cryppo.encrypt_with_derived_key("Aes256Gcm", "Pbkdf2Hmac", "passphrase")
    ...> |> Cryppo.serialize()

`Cryppo.RsaSignature`:

    iex> private_key = Cryppo.generate_encryption_key("Rsa4096")
    iex> "data to encrypt"
    ...> |> Cryppo.Rsa4096.sign(private_key)
    ...> |> Cryppo.serialize()

---

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