Abstract
This document specifies ASH (Anonymous Secure Handoff), a secure messaging protocol designed for high-security, low-frequency communication. ASH provides information-theoretic security — cryptographic guarantees that hold regardless of an adversary's computational power, including quantum computers.
The protocol employs One-Time Pad (OTP) encryption for confidentiality and Wegman-Carter polynomial hashing for authentication. Key establishment occurs through an in-person ceremony using QR codes, eliminating reliance on public-key infrastructure or trusted third parties. A stateless relay server stores only encrypted blobs in RAM, providing message delivery without access to plaintext.
ASH explicitly trades convenience for security: no key recovery, no cloud backup, no multi-device sync, no account system. These constraints are fundamental to the security model. The protocol is suitable for scenarios requiring provable security guarantees, including whistleblowing, journalism source protection, and high-value business communications.
1. Protocol Overview
1.1 One-Time Pad Encryption
ASH uses the One-Time Pad (OTP) cipher, the only encryption method proven to provide information-theoretic security. Unlike computational security (used by AES, RSA, and modern cryptography), OTP security does not depend on mathematical assumptions or computational hardness.
The encryption is simple: each message byte is XOR'd with a corresponding key byte that is:
- Truly random (from entropy sources)
- As long as the message
- Never reused (consumed after use)
- Known only to the two parties
Plaintext: H E L L O (message bytes)
⊕ ⊕ ⊕ ⊕ ⊕ (XOR operation)
Key: 7 K 2 X 9 (random key bytes)
= = = = =
Ciphertext: ? ? ? ? ? (encrypted bytes) Try It Yourself
This interactive demo uses the actual ASH Rust cryptographic core compiled to WebAssembly. Type a message and see how XOR encryption works byte-by-byte.
Live OTP Encryption
Max 16 characters
XOR properties: The same operation encrypts and decrypts. If A ⊕ B = C, then C ⊕ B = A.
Perfect secrecy: Without the key, every possible plaintext is equally likely. "HELLO" could decrypt to any 5-letter message.
1.2 Shannon's Perfect Secrecy
In 1949, Claude Shannon mathematically proved that OTP provides "perfect secrecy": the ciphertext reveals absolutely nothing about the plaintext to an attacker without the key.
Formal definition: A cipher has perfect secrecy if for all plaintexts M and ciphertexts C: P(M|C) = P(M). The probability of any plaintext given the ciphertext equals its prior probability.
This means that without the key, every possible plaintext is equally likely. "HELLO" could decrypt to "WORLD", "PIZZA", or any other 5-letter combination. No amount of computation—not even quantum computers—can determine the original message.
2. System Architecture
ASH consists of four primary subsystems with explicitly defined trust boundaries. Security emerges from clear component separation and minimal infrastructure trust.
┌────────────┐
│ Users │
└─────┬──────┘
│
┌─────▼──────┐
│ iOS App │ (SwiftUI presentation layer)
└─────┬──────┘
│ FFI boundary (UniFFI bindings)
┌─────▼──────┐
│ core │ (Shared Rust Core - cryptographic authority)
└─────┬──────┘
│
┌─────▼──────┐
│ Backend │ (Rust Relay - stateless, untrusted)
└────────────┘ 2.1 Cryptographic Core (ash-core)
The core is the cryptographic and procedural authority of ASH. All security-sensitive behavior is defined here, and all other components must treat it as authoritative.
- • One-Time Pad creation and management
- • Strict pad single-use semantics enforcement
- • Bidirectional pad consumption (Initiator/Responder)
- • OTP encryption and decryption
- • Wegman-Carter 256-bit message authentication
- • GF(2^128) polynomial hashing
- • Mandatory 32-byte message padding
- • Ceremony rules and frame encoding/decoding
- • CRC-32 integrity validation
- • Authorization token derivation
- • Mnemonic checksum generation (6 words, 512-word wordlist)
- • Best-effort memory wiping
ash-core must never: access the network, perform I/O, access OS randomness directly, contain platform-specific code, store data, include UI logic, or log sensitive data.
2.2 Mobile Applications
The iOS application (Android planned) is a presentation and orchestration layer. It invokes core functionality via UniFFI-generated Swift bindings and manages the user interface.
Mobile apps must never: reimplement cryptographic logic, alter OTP behavior, bypass the shared core, invent alternate checksums, persist decrypted messages, or perform silent background actions.
2.3 Backend Relay
The backend is a stateless RAM-only relay. It is intentionally simple and considered untrusted. Messages are held only in memory until ACK or TTL expiry.
Alice Server (RAM) Bob
│ │ │
│ POST /v1/messages │ │
├─────────────────────────►│ (store, start TTL) │
│◄── {blob_id} ────────────│ │
│ │───── SSE: message ──────────►│
│ │ (decrypt) │
│ │◄─── POST /v1/ack ────────────│
│◄── SSE: delivered ───────│ (delete from RAM) │ Backend must never: persist messages to disk, decrypt messages, inspect payload contents, identify users, store data long-term, or implement business logic.
3. Key Establishment Protocol
The ceremony establishes a shared One-Time Pad between two devices through physical proximity. It is designed to be offline, explicit, human-verifiable, and atomic. No network communication occurs during key generation.
3.1 Ceremony Flow
Pad Size Selection
Sender selects pad size via slider, determining message capacity and ceremony duration.
Entropy Collection
OS randomness mixed with required gesture input. User draws patterns while entropy accumulates visually.
Passphrase Exchange
Both parties agree on a shared passphrase (minimum 4 characters). This encrypts QR frames to protect against visual observation.
QR Transfer
Sender displays passphrase-encrypted QR codes. Receiver scans frames, decrypts, validates CRC, and acknowledges.
Mnemonic Verification
Both devices display 6-word checksum. Users verbally confirm match to detect tampering.
Activation
Tokens derived from pad. Conversation becomes active. Messaging available.
3.2 Passphrase Protection
Every ceremony requires a mandatory passphrase that encrypts QR frames during transfer. This protects against visual observation attacks.
| Property | Requirement |
|---|---|
| Minimum length | 4 characters |
| Exchange method | Verbal (spoken between parties) |
| Key derivation | SHA-256 hash of passphrase |
| Frame encryption | XOR with derived key stream |
Defense in depth: The passphrase adds a second layer of protection. Even if QR codes are visually captured, the attacker cannot reconstruct the pad without the passphrase. Both parties must enter the same passphrase for the ceremony to succeed.
3.3 Mnemonic Verification
The mnemonic checksum allows human verification that both devices have identical pads.
| Property | Value |
|---|---|
| Wordlist size | 512 words (custom, not BIP-39) |
| Bits per word | 9 bits (512 = 2^9) |
| Word count | 6 words |
| Verification entropy | 54 bits |
| Word format | 3-7 characters, lowercase ASCII |
Words are optimized for verbal clarity: distinct pronunciation, no homophones, minimal confusion between similar words, and cross-language usability.
Try It Yourself
Generate mnemonic checksums from random pad bytes. Both devices generate identical words from the same pad.
Live Mnemonic Demo
First 7 bytes used for 6 words (54 bits / 8 = 7 bytes)
| Wordlist size | 512 words (custom, not BIP-39) |
| Bits per word | 9 bits (512 = 2^9) |
| Default words | 6 words = 54 bits |
| Collision probability | ~2^-54 (1 in 18 quadrillion) |
Why verbal verification? The mnemonic provides an out-of-band check that both devices have identical pads. Words are chosen for distinct pronunciation — no homophones, no easily confused words.
3.4 Pad Size Options
ASH supports both preset sizes and custom pad sizes from 32 KB to 10 MB. Larger pads support more messages but require longer ceremony transfer times.
| Size | Bytes | Capacity* | Frames |
|---|---|---|---|
| Small (64 KB) | 65,536 | ~680 messages | ~44 |
| Medium (256 KB) | 262,144 | ~2,700 messages | ~175 |
| Large (512 KB) | 524,288 | ~5,400 messages | ~350 |
| Huge (1 MB) | 1,048,576 | ~10,900 messages | ~700 |
| Custom | 32 KB – 10 MB | User-specified | Variable |
* Message capacity = (pad_bytes - 160) / 96. Each message consumes minimum 96 bytes from the pad.
4. Frame Format Specification
Frames partition pad data into scannable QR codes, provide per-chunk integrity verification via CRC-32, and enable ordered reconstruction at the receiver.
4.1 Basic Frame Structure
+------------------+------------------+------------------+------------------+ | Frame Index | Total Frames | Payload | CRC-32 | | (2 bytes BE) | (2 bytes BE) | (N bytes) | (4 bytes BE) | +------------------+------------------+------------------+------------------+
| Field | Size | Description |
|---|---|---|
| Frame Index | 2 bytes | Zero-based index (big-endian) |
| Total Frames | 2 bytes | Total frames in sequence (big-endian) |
| Payload | Variable | Pad bytes (max 1000 bytes) |
| CRC-32 | 4 bytes | CRC of preceding bytes (ISO 3309) |
4.2 Extended Frame Format
For ceremony transfer, an extended format includes metadata and optional encryption.
+-------+-------+------------------+------------------+------------------+------------------+ | Magic | Flags | Frame Index | Total Frames | Payload | CRC-32 | | (1B) | (1B) | (2 bytes BE) | (2 bytes BE) | (max 1500B) | (4 bytes BE) | +-------+-------+------------------+------------------+------------------+------------------+ Magic: 0xA5 (identifies extended format) Flags: Bit 0 = ENCRYPTED, Bit 1 = METADATA
Ceremony Metadata (Frame 0)
When METADATA flag is set, frame 0 contains ceremony settings:
5. Messaging Protocol
ASH messages combine OTP encryption, Wegman-Carter authentication, and mandatory padding into a single authenticated frame. Every message provides both information-theoretic confidentiality and information-theoretic authentication.
5.1 Authenticated Message Frame
All messages use this single frame format. The relay receives and stores these frames as opaque blobs.
┌──────────┬──────────┬──────────┬──────────────────┬──────────────────┐
│ Version │ Type │ Length │ Ciphertext │ Auth Tag │
│ (1 B) │ (1 B) │ (2 B BE) │ (N bytes) │ (32 bytes) │
└──────────┴──────────┴──────────┴──────────────────┴──────────────────┘
│ │ │ │ │
│ │ │ │ └─ Wegman-Carter 256-bit MAC
│ │ │ └─ OTP-encrypted padded plaintext
│ │ └─ Ciphertext length (big-endian)
│ └─ Message type: 0x00=text, 0x01=location
└─ Protocol version (currently 1)
Minimum frame size: 4 (header) + 32 (min ciphertext) + 32 (tag) = 68 bytes | Field | Size | Description |
|---|---|---|
| version | 1 byte | Protocol version (1) |
| type | 1 byte | 0x00 = text, 0x01 = location |
| length | 2 bytes | Ciphertext length (big-endian) |
| ciphertext | ≥32 bytes | OTP-encrypted padded plaintext |
| auth_tag | 32 bytes | Wegman-Carter 256-bit authentication tag |
Pad Consumption Per Message
| Component | Size | Purpose |
|---|---|---|
| Auth key (r₁, r₂, s₁, s₂) | 64 bytes | Wegman-Carter MAC computation |
| Encryption key | ≥32 bytes | OTP encryption (= padded plaintext length) |
| Total minimum | 96 bytes | Per message (64 + 32) |
5.2 Message Processing Pipeline
Every message passes through a symmetric pipeline that provides both confidentiality and authentication. The sender encrypts and authenticates; the receiver verifies and decrypts using the same shared pad.
- Pad message to minimum 32 bytes
- Encrypt with OTP (XOR with pad bytes)
- Authenticate with Wegman-Carter MAC
- Assemble frame and send to relay
- Verify MAC (reject if tampered)
- Decrypt with OTP (XOR is symmetric)
- Unpad to extract original message
- Display message, zero used pad bytes
The interactive demo below shows this pipeline in action using the actual Rust cryptographic core compiled to WebAssembly — the same code that runs on devices.
5.3 Wegman-Carter Authentication
The authentication tag is computed using dual polynomial evaluation over the Galois Field GF(2^128). This provides information-theoretic authentication — mathematically proven unforgeable without the pad.
How Wegman-Carter Works
The core idea: treat the message as coefficients of a polynomial, evaluate it at a secret random point r, then mask the result with a one-time pad value s.
Worked Example
Authenticating a 32-byte ciphertext (2 blocks):
A3F1...29F6 (block 1, 16 bytes) 6EC4...D8B2 (block 2, 16 bytes) r = 7B3A...F912 (random point) s = E5C1...8D4A (OTP mask) 3D7F...A2E1 (GF multiplication) D8BE...2FAB D8BE...2FAB ASH uses dual evaluation (r₁, r₂ with s₁, s₂) to produce a 256-bit tag.
Try It Yourself
This interactive demo uses the actual ASH Rust cryptographic core compiled to WebAssembly. Type a message, see how the polynomial is constructed, and verify the authentication tag.
Live Polynomial Hash Demo
538A7B88D5C8FDE72C81DD75BAC188E81843EC3D6E47B36E95A66B1D5197947ECB95172EF07FBE877B593078455CB8C27D6C89F6DC67BF5B6E5827A8119A2B2BP(x) = P(r₁) ⊕ s₁ = ...P(r₂) ⊕ s₂ = ...How it works: The message is padded and encrypted, then split into 128-bit blocks. Each block becomes a coefficient in a polynomial. The polynomial is evaluated at secret points r₁ and r₂ in GF(2^128), then XOR'd with one-time masks s₁ and s₂ to produce the final 256-bit tag.
Why it's secure: Without knowing r, an attacker cannot forge a valid tag for a different message. The probability of guessing is ~2^-128.
Why It's Unforgeable
Without knowing r: An attacker sees only P(r) ⊕ s. The OTP mask s hides P(r) completely. They cannot learn r from a single tag.
To forge a different message M': They need P'(r) ⊕ s = P(r) ⊕ s ⊕ (P(r) ⊕ P'(r)). But P(r) ⊕ P'(r) is unknown without r.
Probability of guessing: For a degree-n polynomial in GF(2^128), there are at most n values where P(r) = P'(r). Probability of collision: n/2^128 ≈ 0.
| Property | Value |
|---|---|
| Tag size | 256 bits (32 bytes) |
| Auth key | 64 bytes: r₁ (16) + r₂ (16) + s₁ (16) + s₂ (16) |
| Field polynomial | x^128 + x^7 + x^2 + x + 1 |
| Forgery probability | ~2^-128 (negligible) |
| Security level | Information-theoretic (unconditional) |
Why dual polynomials? Using two independent evaluations (r₁, r₂) with separate OTP masks (s₁, s₂) provides 256-bit security. A single polynomial would only give ~2^-64 forgery resistance.
Traffic Analysis Protection
All messages are padded to minimum 32 bytes before encryption. Without this, short messages would be distinguishable by size.
Without padding (vulnerable to traffic analysis): "yes" → 3 bytes ┐ "no" → 2 bytes ├─ Distinguishable! "I'll be there" → 13 bytes ┘ With mandatory 32-byte padding: "yes" → 32 bytes ┐ "no" → 32 bytes ├─ All identical size "I'll be there" → 32 bytes ┘ Padding format: [0x00 marker][2-byte length][content][zero fill to 32]
Try It Yourself
See exactly how messages are padded. Type any message and observe the padding format.
Live Padding Demo
2 bytes input
Why padding matters: Without padding, an attacker could fingerprint messages by size. "yes" (3 bytes) vs "no" (2 bytes) would be distinguishable even when encrypted. With minimum 32-byte padding, all short messages look identical.
Attack prevented: Without padding, an adversary observing encrypted message sizes could fingerprint "yes/no" responses, detect typing patterns, or infer conversation topics from message length sequences.
5.4 Bidirectional Pad Consumption
ASH uses a bidirectional consumption model to enable independent messaging by both parties without coordination or collision.
Pad: [████████████████████████████████████████████████████████████████]
↑ ↑
│ │
Initiator (Alice) Responder (Bob)
consumes → ← consumes
Example (100-byte pad):
Start: [░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░]
0 99
Alice sends 20 bytes:
[████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░]
0 19 99
Bob sends 30 bytes:
[████████████████████░░░░░░░░░░░░░░░░░░░░░░██████████████████]
0 19 69 99
Remaining: 50 bytes (indices 20-69) - • Initiator (ceremony starter): Consumes bytes from index 0 forward
- • Responder (ceremony receiver): Consumes bytes from the end backward
- • No overlap: The two fronts never collide (pad exhausted when they meet)
- • Independent: Either party can send without waiting for the other
- • Asymmetric: Alice can use 20%, Bob can use 80% (or any split)
Forward Secrecy
After encryption, the used pad bytes are securely zeroed. Even if an attacker later compromises the device, they cannot decrypt messages encrypted with already-destroyed key material.
5.5 Message Types
ASH v1 supports two message types. Both are encrypted identically — the type is determined by content structure after decryption.
| Type | Format | Size |
|---|---|---|
| Text | UTF-8 string | 1 byte per character (ASCII) or more (Unicode) |
| Location | lat,lng (6 decimal places) | ~25 bytes (e.g., "37.774929,-122.419418") |
No media support: Photos and videos would exhaust pad capacity quickly. ASH intentionally supports only text and one-shot location sharing. This is a security feature, not a limitation.
Message Lifecycle
Sender Relay (RAM) Receiver
│ │ │
│ 1. Pad message to 32 bytes │ │
│ 2. Consume 64+N pad bytes │ │
│ 3. OTP encrypt │ │
│ 4. Compute Wegman-Carter tag│ │
│ 5. Assemble frame │ │
│ │ │
│ POST /v1/messages ──────────► (store frame, start TTL) │
│ ◄── {blob_id} ──────────────│ │
│ │ │
│ │ SSE: new message ───────────►
│ │ 1. Verify tag │
│ │ 2. Decrypt │
│ │ 3. Unpad │
│ │ ◄── POST /v1/ack ───────────│
│ ◄── SSE: delivered ─────────│ (delete from RAM) │
│ │ │
│ 6. Zero used pad bytes │ │ 6. Authorization Token Derivation
Authorization tokens enable API authentication without accounts or identity. Both parties derive the same tokens from the shared pad.
| Token | Pad Bytes | Purpose |
|---|---|---|
| Conversation ID | 0-31 | Identifies the conversation on the relay |
| Auth Token | 32-95 | Authenticates API requests |
| Burn Token | 96-159 | Required for burn operations |
Derivation Process
- Extract specific byte ranges from pad
- XOR-fold to 32-byte output
- Apply domain separation constant
- Multiple mixing rounds for diffusion
- Encode as 64-character lowercase hex
Security Properties
- Deterministic: Same pad produces same tokens on both devices
- Unpredictable: Without pad, tokens cannot be computed or forged
- Separated: Different tokens for different operations
- Backend-safe: Backend stores only hash(token)
Try It Yourself
Watch how tokens are derived from specific byte ranges of the pad. Hover over each token to highlight its source bytes.
Live Token Derivation
Deterministic: Same pad → same tokens on both devices
Unpredictable: Without pad, tokens cannot be computed or forged
Separated: Different tokens for different operations (defense in depth)
Backend-safe: Backend stores only hash(token), can verify but not forge
Why separate tokens? If an attacker compromises the auth token (e.g., via API logs), they still cannot burn the conversation without the burn token. Each token provides independent authorization for its operation.
7. Trust Model
ASH explicitly defines what each component is trusted to do. This is fundamental to the security model.
| Component | Trust Level | Rationale |
|---|---|---|
| ash-core | Trusted | Cryptographic authority, minimal surface |
| iOS App | Partially | Handles UI, invokes core, stores keys |
| Backend | Untrusted | Never sees plaintext or keys |
| Network | Untrusted | All traffic is encrypted blobs |
| User | Trusted | Must perform ceremony correctly |
Design consequence: ASH deliberately avoids background synchronization, convenience features, user accounts, key recovery, cloud storage, and analytics. All constraints are intentional.
Glossary
- Ceremony
- The in-person key establishment process between two devices, resulting in a shared One-Time Pad.
- GF(2^128)
- Galois Field with 2^128 elements. A finite field used for polynomial arithmetic in Wegman-Carter authentication.
- Information-theoretic security
- Security guaranteed by mathematical proof, not computational assumptions. Holds against adversaries with unlimited computing power.
- Initiator
- The party who starts the ceremony and generates the pad. Consumes pad bytes from index 0 forward.
- One-Time Pad (OTP)
- Encryption method using XOR with a random key equal in length to the message, used exactly once.
- Pad
- The shared random key material generated during ceremony. Consumed bidirectionally for encryption and authentication.
- Perfect secrecy
- Shannon's definition: ciphertext reveals no information about plaintext. P(M|C) = P(M) for all messages M and ciphertexts C.
- Responder
- The party who receives the pad during ceremony. Consumes pad bytes from the end backward.
- Wegman-Carter MAC
- Message authentication code using polynomial evaluation over a finite field, providing information-theoretic authentication.
References
Cryptographic Foundations
- Shannon, C.E. (1949) — "Communication Theory of Secrecy Systems" — Mathematical proof of perfect secrecy for One-Time Pad encryption.
- Wegman, M.N. & Carter, J.L. (1981) — "New Hash Functions and Their Use in Authentication and Set Equality" — Information-theoretic message authentication.
- FIPS 180-2 — SHA-256 specification used for passphrase key derivation.
- ISO 3309 / ITU-T V.42 — CRC-32 polynomial used for frame integrity verification.
Galois Field Mathematics
- NIST SP 800-38D — GF(2^128) field operations and the irreducible polynomial x^128 + x^7 + x^2 + x + 1 used in GCM (same field as Wegman-Carter).
- Bernstein, D.J. (2005) — "The Poly1305-AES message-authentication code" — Related polynomial MAC construction.
Security Analysis
- Rogaway, P. (2000) — "Authenticated-Encryption with Associated-Data" — Formal definitions of authenticated encryption security.
- Liu, H. et al. (2019) — "Traffic Analysis of Encrypted Messaging" — Why message padding matters for privacy.
Revision History
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0.0-draft | 2025-01-22 | tmihalicka | Initial draft for review |
Feedback & Discussion
This whitepaper is a living document. We welcome feedback, questions, and suggestions from the community.
For detailed security analysis, see Security Model. For ethical considerations, see Ethics Statement.