Oboron Protocol Specification

Spec version: v0 (initial)

For a quick start and project overview, see Home. For the CLI specification, see cli.html.

Contents


1. Formats

An Oboron format represents the full transformation of the plaintext to the encrypted text (obtext), including:

  1. Encryption: Plaintext UTF-8 string encrypted to ciphertext bytes using a cryptographic algorithm
  2. Encoding: The binary payload is encoded to a string representation

1.1 Scheme + Encoding = Format

Formats combine a scheme (cryptographic algorithm) with an encoding (string representation):

Given an encryption key, the format thus uniquely specifies the complete transformation from a plaintext string to an encoded obtext string.

Formats are represented by identifiers:

API Notes:

1.2 Encodings

FAQ: Why use Crockford's base32 instead of the RFC standard one?

Crockford's base32 alphabet minimizes the probability of accidental obscenity words, which is important when using with short prefixes: Whereas accidental obscenity is not an issue when working with full encrypted outputs (as any such words would be buried as substrings of a 28+ character long obtext), it may become a concern when using short prefixes as references or quasi-hash identifiers.

1.3 Schemes

Schemes define the encryption algorithm and its properties, classified into tiers:

Scheme Tiers

Scheme Properties

The second letter of the scheme ID further describes the properties of the scheme:

Scheme Cryptographic Algorithms

The remaining two letters in scheme IDs indicate the algorithm:

Summary Table

Scheme Algorithm Deterministic? Authenticated? Notes
ob:aasv AES-SIV Yes Yes General purpose, deterministic
ob:aags AES-GCM-SIV Yes Yes Deterministic alternative
ob:apsv AES-SIV No Yes Maximum privacy protection
ob:apgs AES-GCM-SIV No Yes Probabilistic alternative
ob:upbc AES-CBC No No Unauthenticated - use with caution

Key Concepts:

Choosing a Scheme

Note on encryption strength: All a-tier and u-tier schemes MUST use 256-bit AES encryption. The z-tier uses 128-bit AES for performance in non-security contexts.


2. Algorithm

Oboron combines encryption and encoding in a single operation, requiring specific terminology:

The cryptographic ciphertext (bytes, not string) is an internal implementation detail, NOT exposed in the public API.

The high-level process flow is:

enc operation:
    [plaintext] (string)
      -> encryption
      -> [ciphertext] (bytes)
      -> encoding
      -> [obtext] (string)

dec operation:
    [obtext] (string)
      -> decoding
      -> [ciphertext] (bytes)
      -> decryption
      -> [plaintext] (string)

The above diagram is conceptual; actual implementation includes scheme-specific steps like scheme byte appending and (for z-tier schemes only) optional ciphertext prefix restructuring. With this middle-step included, the diagram becomes:

enc operation:
    [plaintext]
      -> encryption
      -> [ciphertext]
      -> oboron pack
      -> [payload]
      -> encoding
      -> [obtext]

dec operation:
    [obtext]
      -> decoding
      -> [payload]
      -> oboron unpack
      -> [ciphertext]
      -> decryption
      -> [plaintext]

In a-tier and u-tier schemes, the difference between the payload and the ciphertext is in the 2-byte scheme marker that is appended to the ciphertext, enabling scheme autodetection in decoding.

2.1 Padding Design

Oboron's CBC schemes use a custom padding scheme optimized for UTF-8 strings:

Rationale: Oboron is defined to operate exclusively on UTF-8 strings, not arbitrary binary data. This is a protocol-level requirement: all enc operations MUST accept a UTF-8 string input and all dec operations MUST return a UTF-8 string. The 0x01 padding byte can never appear in valid UTF-8 input, ensuring unambiguous decoding. Under the UTF-8 input constraint, this padding is functionally equivalent to PKCS#7 and does not weaken security. Implementations MUST enforce the UTF-8 constraint, eliminating padding ambiguity errors at runtime.


3. Key Management

3.1 Single Master Key Model

Oboron uses a single 512-bit master key partitioned into algorithm-specific subkeys:

Design Rationale: This approach prioritizes low latency for short-string encryption. No hash-based KDF (e.g., HKDF) is used, as this would dominate runtime for intended workloads.

The master key MUST NOT leave the application. Algorithm-specific keys MUST be extracted on-the-fly and MUST NOT be cached or stored.

FAQ: Why use a single key across all schemes?

3.2 Key Format

The default key input format is base64. This is consistent with Oboron's strings-first API design. As any production use will typically read the key from an environment variable, this allows the string format to be directly fed into the constructor.

The base64 format was chosen for its compactness, as an 86-character base64 key is easier to handle manually (in secrets or environment variables management UI) than a 128-character hex key.

While any 512-bit key is accepted by Oboron, the keys generated by Oboron's key generation utilities MUST NOT include any dashes or underscores, in order to ensure the keys are double-click selectable, and to avoid any human visual parsing confusion due to underscores.

3.3 Valid Base64 Keys

Important technical detail: Not every 86-character base64 string is a valid 512-bit key. Since 512 bits requires 85.3 bytes when base64-encoded, the final character is constrained by padding requirements. When generating keys, implementations MUST use one of the following methods:

  1. use Oboron's key generation utility
  2. generate random 64 bytes, then encode as base64
  3. generate random 128 hex characters, then convert hexadecimal to base64

3.4 Alternative Key Interfaces

Implementations SHOULD support the following key input formats in addition to the default base64 format:


4. Properties

4.1 Referenceable Prefixes

If you've used Git, you're already familiar with prefix entropy: you can reference commits with just the first 7 characters of their SHA1 hash (like git show a1b2c3d). This works because cryptographic hashes distribute entropy evenly across all characters.

Oboron schemes exhibit similar prefix quality. Consider these comparisons:

Short Reference Strength:

Collision Resistance:

For a 1-in-a-million chance of two items sharing the same prefix:

(These estimates assume uniform ciphertext distribution under a fixed key.)

Practical Implications:

In a system with 1,000 unique items using 7-character Oboron prefixes:

This enables Git-like workflows for moderate-scale systems: database IDs, URL slugs, or commit references that are both human-friendly and cryptographically robust for everyday use cases.

4.2 Deterministic Injectivity

Comparing the prefix collision resistance in the previous section, Oboron and standard hashing algorithms were compared against each other. But when we consider the full output, then they are not on the same plane: while SHA1 and SHA256 collision probabilities are astronomically small, they are never zero, and the birthday paradox risk can become a factor in large systems even with the full hash. Oboron, on the other hand, is a symmetric encryption protocol, and as such it is collision free (although applying this label to an encryption protocol is awkward): for a fixed key and within the block-cipher domain limits, Oboron is injective (one-to-one), i.e. two different inputs can never result in the same output.

4.3 Performance Comparison

Oboron is optimized for performance with short strings, often exceeding both SHA256 and JWT performance while providing reversible encryption.

Note: As a general-purpose encryption protocol, Oboron is not a replacement for either JWT or SHA256. We use those two for baseline comparison, as they are both standard and highly optimized libraries.

Note: Benchmark data is from the Rust reference implementation.

Scheme 8B Encode 8B Decode Security Use Case
ob:aasv 334 ns 364 ns Secure + Auth Balanced performance + security
JWT 550 ns 846 ns Auth only* Signature without encryption
SHA256 191 ns N/A One-way Hashing only

* Note: JWT baseline (HMAC-SHA256) provides authentication without encryption. Despite comparing against our stronger a-tier (secure + authenticated), Oboron maintains performance advantages while providing full confidentiality.

Performance advantages:

4.4 Output Length Comparison

Method Small string output length
ob:aasv 31-48 characters
ob:apsv 56-74 characters
SHA256 64 characters
JWT 150+ characters

A more complete output length comparison is given in the Appendix.


5. Protocol API

All Oboron implementations MUST provide the following abstract interface.

5.1 Core Operations

5.2 Codec Construction

A codec MUST be constructible from a key and a format specifier. Implementations MUST support construction from a base64 key string (primary interface), as well as from a hex key string or raw key bytes.

Rust:

use oboron::AasvC32;

let ob = AasvC32::new(
    &env::var("OBORON_KEY")?
)?;

Python:

from oboron import AasvC32
import os

ob = AasvC32(os.getenv("OBORON_KEY"))

5.3 Key Generation

All implementations MUST provide a key generation utility that produces a valid 512-bit key encoded as a base64 string (86 characters, URL-safe alphabet, no padding characters).

Rust:

let key = oboron::generate_key();
cargo run --bin keygen

Python:

key = oboron.generate_key()
python -m oboron.keygen

6. Compatibility

Oboron implementations MUST maintain full cross-language compatibility:

All implementations MUST pass the common test vectors.


Appendix: Obtext Lengths

mock1 is a non-cryptographic scheme used for testing, whose ciphertext is equal to the plaintext bytes (identity transformation). It is included in the tables below as baseline.

(Note: mock1 is a non-production scheme for testing purposes only)

Base32 encoding (b32/c32)

Format 4B8B12B 16B24B32B 64B128B
mock1.b32 1016 2329 4255 106208
aags.b32 3642 4855 6880 132234
aasv.b32 3642 4855 6880 132234
apgs.b32 5561 6874 87100 151253
apsv.b32 6168 7480 93106 157260
upbc.b32 5555 5555 8080 132234
zrbcx.b32 2929 2929 5555 106208

Base64 Encoding (b64)

Format 4B8B12B 16B24B32B 64B128B
mock1.b64 814 1924 3546 88174
aags.b64 3035 4046 5667 110195
aasv.b64 3035 4046 5667 110195
upbc.b64 4646 4646 6767 110195
apgs.b64 4651 5662 7283 126211
apsv.b64 5156 6267 7888 131216
zrbcx.b64 2424 2424 4646 88174

Hex Encoding (hex)

Format 4B8B12B 16B24B32B 64B128B
mock1.hex 1220 2836 5268 132260
aags.hex 4452 6068 84100 164292
aasv.hex 4452 6068 84100 164292
upbc.hex 6868 6868 100100 164292
apgs.hex 6876 8492 108124 188316
apsv.hex 7684 92100 116132 196324
zrbcx.hex 3636 3636 6868 132260