# `ExWapp.Signal.Encryption`
[🔗](https://github.com/elchemista/ex_wapp/blob/v0.1.5/lib/ex_wapp/signal/encryption.ex#L1)

High-level Signal encryption/decryption for WhatsApp messages.

Handles the full flow of:
1. Fetching prekeys for new recipients
2. Creating/using Signal sessions
3. Encrypting outgoing messages
4. Decrypting incoming messages

# `decrypt_from_sender`

```elixir
@spec decrypt_from_sender(pid(), String.t(), binary(), atom()) ::
  {:ok, binary()} | {:error, term()}
```

Decrypts an incoming message.

# `decrypt_from_sender_sync`

```elixir
@spec decrypt_from_sender_sync(
  any(),
  any(),
  String.t(),
  binary(),
  atom() | String.t(),
  keyword()
) ::
  {:ok, binary(), any()} | {:error, term()}
```

Decrypts an incoming message without GenServer calls (safe inside Session handlers).

A prekey envelope with `state: "false"` consumes its one-time prekey after
successful authentication but does not save or replace a Signal session.

# `encrypt_for_recipient`

```elixir
@spec encrypt_for_recipient(pid(), String.t(), binary()) ::
  {:ok, binary(), :prekey | :whisper} | {:error, term()}
```

Encrypts a message for a recipient.

Will fetch prekeys and create a session if needed.
Returns the encrypted payload and whether it's a prekey message.

# `encrypt_for_recipient_sync`

```elixir
@spec encrypt_for_recipient_sync(any(), any(), String.t(), binary(), map()) ::
  {:ok, binary(), :prekey | :whisper, any()} | {:error, term()}
```

Encrypts a message for a recipient (synchronous version - no GenServer calls).

This avoids deadlock when called from within a GenServer handle_call.

# `pad_message`

```elixir
@spec pad_message(binary()) :: binary()
```

Pads plaintext according to WhatsApp's padding scheme.

WhatsApp uses PKCS7-like padding with random suffix to obscure message length.

# `unpad_message`

```elixir
@spec unpad_message(binary()) :: binary()
```

Unpads a decrypted message.

# `unpad_message`

```elixir
@spec unpad_message(binary(), integer() | String.t() | nil) :: binary()
```

---

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