OV Message: Technical White Paper

Updated: May 2026

1. Introduction

OV Message is an end-to-end encrypted messaging application that operates without a centralized server. Messages are encrypted before sending and decrypted upon receipt, regardless of the transport channel used. The current implementation uses the SMS network, but the encryption protocol is transport-agnostic. It works over any channel capable of transmitting text.

Serverless architecture: This deliberate choice eliminates a single point of failure, removes the need to trust a third-party operator, and requires no Internet connection.

This document describes the cryptographic mechanisms used, the design choices, and the known limitations of the system.

2. Threat Model

2.1 Covered Threats

Channel Interception

Operator, ISP, network attacker: E2E encryption, the channel only sees ciphertext.

Modification in Transit

HMAC-SHA256, any alteration invalidates the authentication tag.

Message Replay

Anti-replay through tag storage (128 bits, clock-independent).

Frequency Analysis

Stream cipher based on SHA3-256, no fixed character-by-character correspondence.

Known Plaintext

Random per-message index; a (plaintext, ciphertext) pair does not help for another message.

Phishing

Fortress Mode, automatic deletion of unauthenticated messages.

Forensic extraction

Cellebrite, JTAG: KEK/DEK, keys encrypted at rest, DEK destroyed on lock.

Background seizure

Native auto-lock, process kill, RAM freed by the OS.

Physical coercion

Panic Mode, data destruction via alternate password.

Screenshot

System anti-screenshot flag on all application windows.

Cloud backup

Backup disabled on all domains (cloud, local, transfer).

Brute force

Argon2id (64 MB per attempt) + 3 failures = automatic Panic.

Deep links

Deep links blocked when a password is active.

Downgrade

If a key exists, the application systematically encrypts messages intended for the relevant contact.

Contact compromise

Per-contact isolation, each key produces independent alphabets and MAC keys.

Notification leak

Anonymized notifications (Fortress Mode), no name, no preview.

2.2 Out of scope

Operating system compromise (active root/jailbreak with keylogger). Side-channel attack on cryptographic hardware.

3. General architecture

3.1 Technical stack

ComponentTechnology
FrameworkReact Native 0.83 / Expo 55
EngineHermes (compiled bytecode)
CryptographyNative OpenSSL bindings (SHA3-256, HMAC-SHA256, AES-256-GCM, HKDF, Argon2id) + @noble/post-quantum (Hybrid KEM ML-KEM-768 + X25519, FIPS 203)
Sensitive storageAndroid Keystore
Non-sensitive storageLocal database

3.2 Data separation

Contact keys

Secure keystore: Android Keystore + DEK encryption (AES-256-GCM)

Hashed passwords

Secure keystore: Android Keystore

Salt and canary

Secure keystore: salt for DEK derivation and encrypted canary to verify the password at login

Conversations

Local storage: stored in encrypted form (OV format)

3.3 Design principle

Separation of responsibilities: All cryptographic logic is isolated in a dedicated services layer, separated from the user interface. Each service has a single responsibility.

4. Message encryption protocol

4.1 Overview

OV Message uses a hash-based stream cipher. Each character of the message is encrypted individually using a substitution index derived from SHA3-256, depending on the position, a random index unique to the message, and a subkey derived from the contact key.

Not a classical substitution cipher: There is no fixed mapping table between plaintext characters and ciphertext characters.

4.2 Transport constraint

Standard primitives (AES-CTR, ChaCha20) produce binary output. Using them on an SMS channel would require additional encoding (Base64, Base85) that increases the message size by 33 to 50%. On SMS, every character counts.

The OV Message cipher operates directly in Unicode space. Plaintext is transformed into ciphertext without going through an intermediate binary representation. The ratio is 1:1. One plaintext character produces one ciphertext character.

The chosen design uses SHA3-256 as a position-indexed pseudorandom generator, with a random index per message and a subkey derived by HKDF. Each character is encrypted independently with 256 bits of entropy per position.

Assumed trade-off: A non-standard cipher in exchange for an optimal size ratio over a bandwidth-limited channel. Standard primitives (AES-256-GCM, HKDF-SHA256, HMAC-SHA256) are used for all other cryptographic operations.

4.3 Operating principle

  1. Message normalization (Unicode NFC, line breaks standardized)
  2. Generation of a random index (CSPRNG)
  3. Derivation of a subkey unique to the message via HKDF-SHA256
  4. Derivation of a contact-specific cipher alphabet (deterministic permutation)
  5. Character-by-character encryption: each position uses SHA3-256 with the subkey, the position, and the index to produce a substitution index within the derived alphabet.
  6. Generation of the HMAC-SHA256 tag (see section 5)
  7. Formatting of the encrypted message with the index and the tag

Cryptographic uniqueness: Each message uses a cryptographically independent subkey. Two identical messages sent to the same contact produce different ciphertexts.

4.4 Security properties

Confusion

SHA3-256 at each position, non-linear relationship between plaintext and ciphertext.

Diffusion

The random index changes the entire ciphertext for the same message.

Anti-frequency analysis

No fixed character-to-character mapping.

Anti-known-plaintext

Unique sub-key per message, knowing one (plaintext, ciphertext) pair does not help for another message.

4.5 Alphabets

The system uses Unicode alphabets designed to cover 100+ languages as input and produce output in a distinct Unicode space.

5. Integrity and authentication (HMAC)

5.1 MAC key derivation

The MAC key is derived independently from the encryption key via HKDF-SHA256 with domain separation. Each conversation produces a unique MAC key.

5.2 Tag computation

The HMAC-SHA256 tag is computed over the concatenation of additional authenticated data (conversation identifier, message index) and the ciphertext. The tag is truncated to 128 bits.

5.3 Properties

Anti-tampering

Any modification of the ciphertext invalidates the tag.

Anti-replay

The unique random index per message makes each tag unique.

Anti-downgrade

Tag verification is mandatory upon decryption.

Domain separation

The MAC key is derived with a different info string from the file AES key.

6. Key management

6.1 Contact key generation

Each contact key is generated locally with a CSPRNG. Keys have variable length and high entropy. Variable length makes deducing the key size from metadata difficult.

6.2 Key exchange

OV Message offers two out-of-band exchange methods:

MethodChannelMechanism
In personQR code physically scannedDirect key transmission
RemoteSMS + trusted voice/video channelHybrid KEM ML-KEM-768 + X25519, SAS verification

Hybrid post-quantum pairing: The initiator generates a hybrid key pair (ML-KEM-768 + X25519) and transmits the public key via SMS (format OVPK:<sessId>:I:<base64>). The responder encapsulates a shared secret with this public key and returns the ciphertext via SMS. After decapsulation, both sides have the same shared secret, from which the following are derived:

  • The contact key (via HKDF-SHA256, info string OV_PQHybrid_ContactKey_v1)
  • A SAS (Short Authentication String) of 12 hex characters (48 bits of entropy), derived from the same secret via a distinct info string (OV_PQHybrid_SAS_v1)

Both parties compare the SAS via a trusted external channel (voice, video). If the codes match, the key is established. Ephemeral keys are destroyed, the shared secret is erased from RAM. The SMS OVPK can therefore be publicly observed without compromising security.

Why hybrid? The final shared secret combines the ML-KEM secret (designed to resist quantum computers) and the X25519 secret (resistant to modern classical attacks). An attacker must break both to recover the contact key. This is intended to neutralize the strategy « harvest now, decrypt later » : an adversary recording the SMS today would need, to decapsulate ML-KEM-768, a cryptographically relevant quantum computer, beyond foreseeable capabilities in the near future.

6.3 Pre-generated key pool

Generation

A key pool pre-generated locally for each contact. Each key indexed by a number.

Encrypted export

Pool encrypted with AES-256-GCM (key derived by HKDF-SHA256) before exchange.

Rotation

Selection by index, only the number transits. Never the key itself.

Permanent deletion

Each consumed key is physically deleted, allowing manual forward secrecy at the rotation level.

6.4 Key derivation

UsageAlgorithmDetails
Password hashingArgon2id (m=64 MB, t=3, p=1, L=32)Random salt per hash
DEK (master key)Argon2id + HKDF-SHA256Info string OV_DEK_v1, dedicated salt
AES file keyHKDF-SHA256Dedicated info string
AES pool keyHKDF-SHA256Dedicated info string
MAC keyHKDF-SHA256Dedicated info string + conversation ID
Hybrid exchange (KEM)ML-KEM-768 + X25519 + HKDF-SHA256Ephemeral keys per session, domain separation for contactKey vs SAS
Charset permutationDeterministic derivationDifferent input per contact

Domain separation: Each context uses a distinct info string or salt, ensuring that the same contact key produces independent derived keys for each use.

7. Protection of keys at rest (KEK/DEK)

7.1 Objective

Protect contact keys against forensic extraction (Cellebrite, JTAG, RAM extraction) in the event of physical seizure of the phone.

7.2 Architecture

DEK (Data Encryption Key)

Symetric key of 256 bits, deterministically derived from the password via Argon2id (m=64 MB, t=3, p=1, L=32) then HKDF-SHA256 with the info string OV_DEK_v1. Never stored, regenerated at each login, loaded in RAM only, destroyed on lock (process kill).

Canary verification

At login, an AES-256-GCM encrypted canary under the DEK is decrypted to validate the password. An incorrect password produces a different DEK that cannot decrypt the canary: immediate detection without revealing the correct DEK value.

Contact keys

Each key encrypted individually with the DEK using AES-256-GCM. Lazy decryption (on demand).

7.3 Backward compatibility

Without a password configured, the keys remain in the secure keystore (protected by Android Keystore). Migration to encrypted mode is transparent upon the first password configuration.

8. File encryption

8.1 Algorithm

Files shared between contacts are encrypted with AES-256-GCM. The AES key is derived via HKDF-SHA256 from the contact key and a random 16-byte salt, with a dedicated info string. A 12-byte IV is randomly generated.

Total overhead: 44 bytes (16-byte salt + 12-byte IV + 16-byte tag).

8.2 Integrity checks

GCM authentication guarantees the integrity of the ciphertext and AAD. A file name consistency check is performed after decryption.

9. Anti-replay protection

9.1 Clockless design

Clock independent: No timestamp, no TTL, no synchronisation required between devices.

  • Each received HMAC tag (128 bits) is stored locally.
  • A message with a previously seen tag is silently discarded.
  • Storage is partitioned by contact and by direction (sending/receiving).

9.2 Alert thresholds

ThresholdAction
1,500 stored tagsAlert: key rotation recommended
1,800 stored tagsAlert: key rotation strongly recommended
1,999 stored tagsAlert: urgent key rotation

9.3 Key rotation

At each key rotation, the replay store is cleared. The new key produces a new MAC key, so old tags cannot be replayed.

10. Fortress Mode (anti-phishing)

10.1 Principle

Fortress Mode is an active filter that automatically deletes any incoming message that could not be authenticated. It constitutes protection against phishing, identity spoofing, and unsolicited messages.

10.2 3-step filtering

Step 1: Known sender

The number is an OV Message contact with an encryption key. Failure = message deleted.

Step 2: OV format

The message is in OV encrypted format. Failure = message deleted.

Step 3: Authentication

The HMAC-SHA256 tag is valid and decryption succeeds. Failure = message deleted.

10.3 Dual-layer filtering

Native layer: intercepts messages before they are broadcast to the system. Unknown numbers are blocked immediately, without notification.

Application layer: full cryptographic validation (HMAC + decryption) for messages that have passed the first filter.

10.4 Anonymized notifications

In Fortress Mode, notifications are generic (no sender name, no content preview). Notifications displayed on the lock screen do not reveal the sender's identity or the content of the message.

11. Forensic resilience

11.1 Panic Mode

Two levels of emergency destruction. Triggered by a dedicated alternate password. If self-destruction is enabled, 3 password failures automatically trigger Panic Mode.

DataPanic (complete destruction)Panic keys (keys only)
Contact keysDestroyedDestroyed
DEK / KEKDestroyedDestroyed
Physical SMSDeletedPreserved
Address book contactsDeletedPreserved
Conversations, settingsErasedPreserved
Encrypted messagesDeletedPresent but undecipherable
Memory caches (RAM)Overwritten then flushedFlushed
ReversibilityNoNo

Discreet: No visual alert, the application opens as after a normal login. The mode is designed not to betray its activation to an attacker who would not have a reference to the previous content.

11.2 Native auto-lock (process kill)

A native module schedules process termination via an exact system alarm, immune to Doze mode. When the timer expires, the process is killed by the OS and all RAM is freed (DEK, keys, sensitive data). If the application returns to the foreground before expiration, the alarm is cancelled.

11.3 Additional protections

Anti-screenshot

System flag preventing screen capture and recording.

Anti-cloud backup

Backup disabled on all domains (cloud, local, transfer).

Secure storage

Android Keystore for secrets (extraction requires PIN/biometrics).

12. Known limits and trade-offs

12.1 No Perfect Forward Secrecy

The application operates without a permanent key exchange server, making the Double Ratchet impractical. A hash ratchet would cause desynchronization on lost or reordered messages.

Security in static key mode: Each message derives an independent subkey via HKDF-SHA256. Compromise of a subkey does not compromise other messages. The key pool provides manual forward secrecy. Deletion of a consumed key renders past messages undecipherable.

Hybrid pairing and FS: The ML-KEM-768 + X25519 pairing generates keys ephemeral per session, destroyed after derivation of the contact key. The pairing session itself is therefore forward-secret : compromising the phone after pairing does not allow replaying this session. However, the derived contact key remains static (shared between both devices). Forward secrecy at the level message still relies on manual rotation via the key pool.

12.2 Transport metadata

The transport channel exposes metadata (sender, recipient, timestamp). OV Message cannot hide this information because it is part of the underlying transport protocol.

12.3 Padding

Messages are deterministically padded. An observer can approximate the length of the plaintext message. This trade-off is accepted because transport metadata already leaks more information than the message length.

12.4 Audit status

Audit: The stream cipher based on SHA3-256 is an original design whose security relies on the well-established PRF properties of SHA3-256. An independent formal cryptographic audit is planned and will be published. All other cryptographic operations use standard audited primitives.

12.5 Initial key exchange

Security relies on the confidentiality of the shared key and the authenticity of the verification channel:

  • In person: the QR code is transmitted directly, without an intermediary channel.
  • Remotely: hybrid pairing exposes public keys via SMS (observable), but confidentiality relies on the cryptographic robustness of the hybrid KEM ML-KEM-768 + X25519. Identity verification relies on comparing the 12-character hex SAS via an external trusted channel (recognized voice, video). A MITM attacker would need to intercept the SMS and impersonate the voice/face of the correspondent on the verification channel. The latter is therefore the critical link.

13. Positioning

OV Message targets a threat model that conventional messengers (Signal, WhatsApp, Olvid) do not address: operation without a server or Internet connection, resilience to physical phone seizure, and emergency data destruction under duress.

Multi-layer Panic Mode

Complete destruction or keys only, silent on the interface side.

Native auto-lock

Process termination, RAM release by the OS.

Fortress Mode

3-step anti-phishing filtering with anonymized notifications.

Sustainability

Zero infrastructure cost, no dependency on a third party, independent of centralized servers.

14. Summary of cryptographic parameters

ComponentParameterValue
Message encryptionPosition-based hashSHA3-256 (256 bits)
Message encryptionRandom indexHigh entropy (CSPRNG)
Message encryptionPer-message subkeyHKDF-SHA256 (256 bits)
Message encryptionAlphabetsDerived per contact
HMACAlgorithmHMAC-SHA256
HMACTag128 bits
HMACDerivationHKDF-SHA256 with domain separation
Argon2idMemory (m)64 MB
Argon2idIterations (t)3
Argon2idParallelism (p)1
Argon2idOutput256 bits
AES-256-GCMKey256 bits
AES-256-GCMIV96 bits
AES-256-GCMTag128 bits
KEK/DEKDEK256 bits, deterministically derived (Argon2id + HKDF-SHA256, info OV_DEK_v1)
KEK/DEKPassword verificationCanary encrypted with AES-256-GCM under the DEK
Key generationEntropyHigh entropy (CSPRNG)
Hybrid KEMML-KEM-768FIPS 203, NIST level 3 (post-quantum)
Hybrid KEMX25519128 bits of classical security
Pairing derivationHKDF-SHA256Domain separation contactKey / SAS
SASTruncated HMAC-SHA25612 hex chars (48 bits), out-of-band comparison
Ephemeral keysDestroyed after exchange, live-only sessions (RAM only, no persistence)
Anti-replayStoragePer contact, per direction
FilesEncryptionAES-256-GCM + HKDF

OV Message: encryption without server, without dependency, without compromise on security.