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

Signal Protocol wire format implementation.

Based on the official Signal Protocol specification and libsignal-protocol-java.

Wire format:
- SignalMessage: version_byte || protobuf || mac(8 bytes)
- PreKeySignalMessage: version_byte || protobuf

Key format:
- Public keys are serialized as: 0x05 || 32-byte-key (33 bytes total)

Version byte format:
- (current_version << 4) | current_version
- For version 3: 0x33

# `decrypt_aes_cbc`

```elixir
@spec decrypt_aes_cbc(binary(), binary(), binary()) ::
  {:ok, binary()}
  | {:error, :invalid_ciphertext | :invalid_padding | :decrypt_failed}
```

Decrypts ciphertext using AES-256-CBC and validates PKCS7 padding.

# `deserialize_public_key`

Deserializes a public key, removing the type prefix.

# `encode_varint`

Encodes an unsigned integer as a varint.

# `encrypt_aes_cbc`

Encrypts plaintext using AES-256-CBC with PKCS7 padding.

This is the encryption used inside Signal messages (not AES-GCM!).

# `message_type`

Returns the message type atom for the given serialized message.

# `parse_prekey_signal_message`

```elixir
@spec parse_prekey_signal_message(binary()) :: {:ok, map()} | {:error, term()}
```

Parses a serialized PreKeySignalMessage.

Returns map keys:
- `:version_byte`
- `:registration_id`
- `:prekey_id`
- `:signed_prekey_id`
- `:base_key`
- `:identity_key`
- `:message` (inner SignalMessage bytes)

# `parse_signal_message`

```elixir
@spec parse_signal_message(binary()) :: {:ok, map()} | {:error, term()}
```

Parses a serialized SignalMessage.

Returns map keys:
- `:version_byte`
- `:version_and_proto` (used for MAC verification)
- `:mac`
- `:ratchet_key` (32 bytes)
- `:counter`
- `:previous_counter`
- `:ciphertext`

# `serialize_prekey_signal_message`

Serializes a PreKeySignalMessage.

Args:
  - registration_id: sender's registration ID
  - prekey_id: one-time prekey ID (optional)
  - signed_prekey_id: signed prekey ID
  - base_key: ephemeral public key from X3DH
  - identity_key: sender's identity public key
  - signal_message: already-serialized SignalMessage bytes

Returns the serialized prekey message bytes.

# `serialize_public_key`

Serializes a public key with the DJB type prefix (0x05).

# `serialize_signal_message`

Serializes a SignalMessage (whisper message).

Args:
  - ratchet_key: 32-byte sender's current ratchet public key
  - counter: message counter
  - previous_counter: previous chain's counter
  - ciphertext: AES-CBC encrypted message
  - mac_key: key for HMAC
  - sender_identity: sender's identity public key
  - receiver_identity: receiver's identity public key

Returns the serialized message bytes.

# `valid_signal_mac?`

```elixir
@spec valid_signal_mac?(binary(), binary(), binary(), binary(), binary()) :: boolean()
```

Verifies the Signal MAC over `version_and_proto`.

# `verify_signal_mac`

```elixir
@spec verify_signal_mac(binary(), binary(), binary(), binary(), binary()) ::
  {:ok, atom()} | :error
```

Verifies a Signal MAC with compatibility fallbacks used by production WA clients.

Returns `{:ok, strategy}` when a check matches, or `:error` otherwise.

---

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