Design Rationale
This document explains the reasoning behind HPPR’s design decisions.
Why the 🖧 markline
symbol
The 🖧 character (U+1F5A7, three networked computers)
was chosen so that any transport or display that mangles UTF-8 fails
visibly and immediately. If you see ð§ or
? instead, something is broken. No subtle
corruption—the packet is obviously wrong.
Why
//group/api//key not //api/group//key
A ring1 account must explicitly list every group it can access:
//u/chess//, //friends/chess//,
//my-city/chess//. Various approaches were tried to
allow wildcards like //*/chess//, but the complexity
did not add enough features to justify it.
With group first, ACL rules are simple prefix matches. No pattern syntax, no ambiguity about which rule wins.
Why #
is forbidden in Group and API names
The # character is reserved so Keys can embed
group/API references compactly:
//g/a//key/<group>#<api> or
//g/a//key/<group>#.
Without this, you’d need nested paths like
//g/a//key/by-group/<group>/by-api/<api>,
which requires awkward 1+N LIST lookups to enumerate. With
#, a single Key segment holds both identifiers, and a
single LIST returns all entries.
Why “Ring2” not “Group Identity”
Ring2 was originally called “group identity.” The name changed because distributed systems require a fundamental shift in perspective.
The question is always individual: “Am I part of this group? Who else is a member?” There is no central authority to ask. Each node evaluates membership from its own view, using the packets it has.
Any scheme that pretends otherwise—that offers a simple “the server knows”—is hiding complexity. The complexity doesn’t go away; it just becomes implicit and harder to reason about.
“Ring2” signals that this is a distinct authentication layer with its own rules, not a thin wrapper over familiar group semantics.
Why
Link headers have no enforced format
The Link: <tag> <hash> convention is not
validated at the packet level. Earlier designs required strict
parsing, but this added complexity with little benefit.
Even a command like BACKLINKS—which would index references between packets—can simply ignore malformed links. Enforcement at parse time gains nothing; the consumer decides what to trust.
Why Ring1-Name allows
#
Ring1-Name forbids / { } | but explicitly allows
#. This lets a ring1 name encode a group/API pair:
chess-club#tournaments or
my-city#events.
This is useful when a ring1 identity represents access scoped to a specific group and API combination, making the relationship visible in the name itself.
Why ACL rules sort |
before /
ACL rules are sorted with | before /,
both before other characters. This ordering means rules appear
grouped by branch at every level of the tree.
When scanning a sorted rule list, you see: 1. Version-pinned
rules (/|/...) for an exact Key 2. Then child Key paths
(/child/...)
At every branch point, the specific (versioned) rules come before the general (subtree) rules. A human reading the list can predict where any rule will appear without searching.
Why no built-in encryption
HPPR packets are signed, not encrypted. This is deliberate.
Transport encryption is a solved problem. Encryption between two end points is so cheap, simple, and common that a message routinely is encrypted three or four times without noticing: Wi-Fi, VPN, SSH, HTTPS, wireless. WireGuard provides fast, simple, audited tunnels. TLS terminates at reverse proxies. IPsec exists for enterprise networks. Every deployment already has opinions about network security.
Baking encryption into the packet format would mean: - Choosing algorithms that age poorly (see: TLS 1.0, SSH v1) - Forcing key exchange into the protocol (complex, error-prone) - Making packets opaque to intermediate nodes (breaks caching, debugging, auditing)
Instead, HPPR focuses on what HTTP cannot provide: content authenticity via signatures. For confidentiality, use the network layer. A WireGuard tunnel between your devices and your server is stronger protection than any application-layer encryption HPPR could offer.
If your threat model requires end-to-end encryption of packet contents, encrypt the blob data before creating the packet. The application controls the encryption scheme, key management, and recipient selection. HPPR transports the ciphertext; the signature proves who encrypted it.
Why not post-quantum-secure signatures
HPPR uses secp256k1 today. This is a deliberate tradeoff.
I am not convinced that current post-quantum signature schemes have reached a useful level of practical reliability, especially where error behavior, correction, and overall operational simplicity are concerned. The costs are clearer than the benefits right now: much larger signatures, more complexity, and no immediate practical need.
The format was designed to leave room for cryptographic
replacement later. The .H3 suffix exists precisely so
the packet format can change its cryptographic suite in a clean,
explicit way when that becomes necessary.
For now, secp256k1 is an acceptable choice. Systems securing far larger and more obvious targets, such as Bitcoin, rely on the same signature family. That does not make the risk zero, but it keeps HPPR in well-understood territory.
The tradeoff is simple: future-proofing now would impose significant present-day cost for a threat that does not currently justify it.
The hash is also in a different position from the signature. As far as is known, quantum computing does not create a practical collision threat against BLAKE3 at present; the main quantum concern is reduced preimage cost, not suddenly easy collisions.