# Hubert: Distributed Key-Value Store for Secure Multiparty Coordination **BCR-2025-006** **© 2025 Blockchain Commons** Authors: Wolf McNally, Christopher Allen<br/> Date: December 9, 2025 --- ## Abstract Traditional secure messaging suffers a centralization vulnerability: even with end-to-end encryption, centralized servers can surveil. They can determine who is communicating with whom and when those communications occur. Hubert resolves this with a serverless "cryptographic dead-drop" architecture. Encrypted blobs of data are stored at derived keys on a decentralized storage network. The network see only random data blobs at apparently random addresses, never metadata. No single entity controls message flow or retains user logs, and the networks have no insight into the communicating parties or the content they're transmitting. From a technical point of view, Hubert is a distributed key-value storage protocol for secure multiparty transactions that doesn't require persistent connections or synchronous participation. It instead leverages the write-once semantics of public distributed networks to create a trustless coordination layer for the exchange of encrypted messages. Each storage location accepts exactly one write, ensuring message immutability and eliminating race conditions. BitTorrent Mainline DHT and IPFS are both used: small messages (≤1 KB) route through DHT for speed, while large messages route through IPFS automatically. ## Table of Contents - [Hubert: Distributed Key-Value Store for Secure Multiparty Coordination](#hubert-distributed-key-value-store-for-secure-multiparty-coordination) - [Abstract](#abstract) - [Table of Contents](#table-of-contents) - [1. Introduction](#1-introduction) - [1.1 Communication Patterns](#11-communication-patterns) - [1.2 Addressing Patterns](#12-Addressing-Patterns) - [1.3 Storage Patterns](#13-Storage-Patterns) - [1.4 Messaging Patters](#14-Messaging-Patterns) - [2. Design Principles](#2-design-principles) - [2.1 Capability-Based Access Control](#21-Capability-Based-Access-Control) - [2.2 Transport Agnosticism](#22-Transport-Agnosticism) - [2.3 Write-Once Semantics](#23-Write-Once-Semantics) - [3. Security Considerations](#3-security-considerations) - [3.1 What Hubert Protects](#31-what-hubert-protects) - [3.2 What Hubert Does Not Protect](#32-what-hubert-does-not-protect) - [3.3 Ephemeral Messages](#33-No-Forward-Secrecy) - [4. Reference Implementation](#4-reference-implementation) - [4.1 Library API](#41-library-api) - [4.2 Command-Line Tool](#42-command-line-tool) - [4.3 Error Handling](#43-error-handling) - [5. Use Case: FROST Threshold Signing](#5-use-case-frost-threshold-signing) - [5.1 Overview](#51-Overview) - [5.2 Protocol Phases](#52-FROST-over-Hubert-Protocol-Phases) - [5.3 Operational Notes](#53-Operational-Notes) - [6. Future Backends](#6-future-backends) - [6.1 Backend Models](#61-backend-models) - [6.2 Candidate Technologies](#62-candidate-technologies) - [Appendix A: Tech Terminology](#appendix-a-terminology) - [Appendix B: Tech Terminology](#appendix-a-terminology) --- ## 1. Introduction *See [Appendix A](#Appendix-A-Tech-Terminology) for tech terminology and [Appendix B](#Appendix-B-Tradecraft-Terminology) for tradecraft terminology.* Modern cryptographic protocols increasingly require coordination among multiple parties. Distributed key generation ceremonies need commitments and shares flowing between nodes. Threshold signature schemes like FROST demand multiple rounds of message exchange. Secure voting, collaborative custody, and other MPC protocols also need coordination. The conventional approach routes these messages through centralized servers. This creates a single point of failure (SPOF) where the server operator can censor, delay, or selectively deliver messages. A compromised server can also expose the entire coordination graph of participants. Hubert eliminates this centralization by transforming existing public distributed networks into a trustless coordination substrate. Rather than sending messages through a server, participants publish encrypted and obfuscated messages to locations on IPFS or in the BitTorrent Mainline DHT. These locations derive from secrets known as *ARIDs* (Apparently Random Identifiers) shared only among participants. As a result, the storage network sees only random binary blobs published to apparently random addresses. It cannot enumerate participants, correlate messages, or interfere with delivery without hampering the entire network. This methodology is what espionage tradecraft would call a digital *dead-drop*. The ARID is a pre-arranged location where one party leaves material for another to retrieve, with the two parties never meeting. Only those who possess the necessary ARID can locate the message, and only they can retrieve meaningful data, because the ARID also obscures the message's content using encryption. Even if the message were retrieved and unobfuscated, it is still encrypted to a particular recipient courtesy of a steganographic layer: [Gordian Sealed Transaction Protocol (GSTP)](https://github.com/BlockchainCommons/research/tree/main/papers/bcr-2023-014-gstp) provides both end-to-end encryption and authentication. ### 1.1 Communication Patterns Parties pre-coordinate out-of-band before using Hubert: they share encryption/signing public keys (for example, via [XID Documents](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-010-xid.md)) using a secure channel such as Signal or in-person QR exchange and one participant generates an initial ARID . ```mermaid sequenceDiagram actor A as Alice participant S as Signal actor B as Bob A->>B: public key (Alice)<br/>ARID-1 B->>A: public key (Bob) ``` Trust on First Use (TOFU) is also supported: an endpoint vends its XID Document and a fresh ARID over HTTPS, enabling anonymous parties to bootstrap coordination. Once the pre-coordination phase is complete, communications often follow a request-response pattern. Alice creates a message that includes a freshly generated ARID and "writes once" to the original ARID address. Bob retrieves the message, extracts the new ARID, and publishes his response there. Each party includes a new ARID when expecting a reply. ```mermaid sequenceDiagram actor A as Alice participant A1 as ARID-1 participant A2 as ARID-2 actor B as Bob A->>A1: message with ARID-2 A1->>B: message with ARID-2 B->>A2: message with ARID-3 A2->>A: message with ARID-3 ``` Bidirectional and multicast patterns are both supported. ### 1.2 Addressing Patterns Storage keys derive deterministically from ARIDs using HKDF and salt that is specific for the storage meechanism. A few additional steps then reveal the storage location. ```mermaid flowchart TB ARID ARID --> DHT[("DHT")] ARID --> IPFS[("IPFS")] DHT --> DHT_HKDF["HKDF-HMAC-SHA256<br/>+DHT-specific salt"] DHT_HKDF --> Ed25519["Ed25519 seed"] Ed25519 --> Keypair["Signing keypair"] Keypair --> DHT_Loc["DHT public key<br/>(storage location)"] IPFS --> IPFS_HKDF["HKDF-HMAC-SHA256<br/>+IPFS-specific salt"] IPFS_HKDF --> KeyName["IPFS key name"] KeyName --> PeerID["IPNS peer ID"] PeerID --> IPNS_Loc["IPNS address<br/>(storage location)"] ``` ***Mainline DHT:*** * Hubert derives a seed. * Hubert generates an Ed25519 signing key. * Its public half becomes the storage location. ***IPFS:*** * Hubert derives a deterministic IPFS key name. * Hubert creates (or retrieves) an IPNS peer ID. * User later adds content to IPFS to obtain a CID. * Hubert publishes that CID to the IPNS name. ```mermaid flowchart TB ARID ARID --> Obfusc_HKDF["HKDF-HMAC-SHA256<br/>+Obfuscation-specific salt"] Obfusc_HKDF --> ChaCha["ChaCha20<br/>symmetric key"] ChaCha --> Payload["Obfuscated payload<br/>(uniform random bytes)"] ``` The ARID also is used to produce the required signature to write to a storage location. The "obfuscation" key (derived with a third salt) encrypts the payload to appear as uniform random bytes. This encryption is reversible by anyone with the ARID, hence "obfuscation" rather than encryption. ### 1.3 Storage Patterns All stored values are [Gordian Envelopes](https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-003-envelope.md), not arbitrary byte sequences. This constraint provides structural guarantees. Envelopes use dCBOR (deterministic CBOR), ensuring identical byte representations for identical semantics across implementations. Every envelope contains a Merkle-like digest tree, allowing recipients to verify structural integrity without external metadata. The format natively supports encryption, compression, signatures, and holder-based elision, and can represent assertions, hierarchies, and typed data rather than opaque blobs. Requiring envelope values means Hubert inherits these properties without reimplementing them. It also provides the GSTP steganographic layer without requiring separate implementation. ### 1.4 Messaging Patterns A message transmitted by Hubert is a layered onion. * The core message is the body of the message and a new ARID for response. * This content is stored as a Gordian Envelope. * The envelope is encrypted to the private key of the recipient using GSTP. * The encrypted envelope is further obfuscated with encryption using an ARID-derived key. * The envelope is stored in Mainline DHT or IPFS. * The storage is referenced by BEP-44 or IPNS. ## 2. Design Principles The design follows three board principles: capability-based access control, transport agnosticism, and and write-once semantics. These principles provide strong support for independence and openness by empowering users and by blocking platform lock-in. These are [Gordian Principles](https://github.com/BlockchainCommons/Gordian#gordian-principles) that underlie much of Blockchain Commons' work. ### 2.1 Capability-Based Access Control The ARID model offers capability-based access control. The ARID itself is the authorization: a bearer token that grants access to whomever possesses it. Sharing an ARID grants the recipient the same capabilities you have. The storage network never learns who you are. Because each ARID is used once, there is also no long-lived identity to track or compromise. ### 2.2 Transport Agnosticism Hubert defines storage semantics, not network protocols. A common interface abstracts over multiple storage backends, allowing "transport" of messages via multiple means: | Backend | Max Size | Write Latency | Propagation | Persistence | Local Dependencies | | :----------- | :----------- | :------------ | :---------- | :------------------- | :---------------------- | | Mainline DHT | ~1 KB | 1-5s | 5-30s | ~2 hours | None (embedded client) | | IPFS | ~10 MB | 5-30s | 30-120s | 48 hours (DHT entry) | Kubo daemon required | | Hybrid | ~10 MB | Varies | Varies | See above | Kubo (large payloads) | | Local Server | Configurable | <10ms | Immediate | Indefinite | Self-hosted HTTP server | **Definitions:** * ***Backend.*** Chosen storage method. * ***Max Size.*** Maximum message size. * ***Write Latency.*** How long a "put" operation takes. * ***Propagation.*** How long it takes for the value to become reliably retrievable from other nodes. * ***Persistence.*** How long the value remains available without re-announcement or pinning. These backends include the two decentralized storage means already mentioned, Mainline DHT and IPFS, as well as two variants, Hybrid Mode and Local Server. ***Mainline DHT*** requires no external software, as Hubert embeds a DHT client. The BEP-44 items used for indexing expire after approximately 2 hours, so should be re-announced hourly. ***IPFS*** requires a locally running [Kubo](https://docs.ipfs.tech/install/command-line/) daemon, which Hubert communicates with using HTTP RPC. Kubo automatically republishes IPNS records every 4 hours for keys it holds. By default, Hubert does not pin content; unpinned content may be garbage collected. Use `--pin` for messages that must persist beyond a single session. ***Hybrid Mode*** routes messages based on size. Small messages (≤1 KB) go to the DHT. For larger messages, Hubert stores the actual envelope in IPFS under a freshly generated reference ARID, then stores a small reference envelope in the DHT at the original ARID. This reference envelope contains the storage backend indicator, reference ARID, and size. When retrieving, Hubert fetches from DHT first; if it finds a reference envelope, it extracts the reference ARID and fetches from IPFS. This indirection is transparent to callers and combines DHT's speed with IPFS's capacity. Both envelopes are independently obfuscated using their respective ARIDs. ***Local Server*** provides a simple HTTP key-value store for testing. It offers no additional security and requires self-hosting. Hubert's built-in server supports both in-memory storage (ephemeral, fast) and SQLite persistence (durable). This backend is useful for development and scenarios where decentralization is not required. Hubert's transport agnosticism will also allow it to adapt as new distributed storage systems emerge. ### 2.3 Write-Once Semantics Each ARID maps to exactly one storage location that accepts exactly one write. Subsequent write attempts fail. This constraint guarantees immutability once published and eliminates race conditions. Though Mainline DHT and IPFS are both fundamentally tamper-evident, as their keys are bound to their values through hashes, Hubert uses the mutable layers built atop these immutable foundations to allow for the distribution of addresses prior to the creation of content: BEP-44 mutable items for DHT (which are addressed by a cryptographic public key) and IPNS for IPFS (which are addressed by peer ID derived from a key pair). As a result, write-once immutability is achieved through Hubert's policy layer, not the underlying protocol. For DHT's BEP-44, Hubert enforces immutability through sequence number constraints. BEP-44 items include a monotonically increasing sequence number. Hubert always publishes with `seq=1` and never issues updates, so Hubert clients reject any value whose sequence number is not exactly 1, treating it as corruption. If two parties race to write the same location, the DHT's sequence number check ensures at most one succeeds. This methodology also protect Hybrid Mode, since all Hybrid messages have a DHT entry. This means they're protected by the same `seq=1` corruption-detection guarantee. For IPFS' IPNS, Hubert enforces immutability by resolving the IPNS name prior to publication; if it already points to a CID, the write fails. **ARID compromise and denial-of-service.** Because the signing key (for DHT) and key name (for IPFS) derive deterministically from the ARID, anyone who obtains the ARID before the legitimate writer publishes can race to write first, causing denial-of-service. However, they cannot change existing content because of Hubert's write-once guarantees, nor can they decrypt published content (which is encrypted with the recipient's private key). > **Future enhancement.** A stronger design would derive only the *public* storage location from the ARID while using a separate ephemeral signing key known only to the writer. After publication, the writer would discard this private key, making the location cryptographically immutable rather than policy immutable. This would eliminate the race-to-write vulnerability at the cost of preventing legitimate re-announcement for DHT persistence. ## 3. Security Considerations Defense in depth comes through layered protections. ### 3.1 What Hubert Protects **Write-once integrity.** Once published, a message cannot be modified or replaced. The BEP-44 sequence number mechanism and Hubert's IPNS policy layer enforce this. **Unlinkable storage locations.** The DHT public key or IPNS name reveals nothing about the ARID that generated it. Observers cannot correlate storage locations with the secrets that address them, nor derive the ARID from the storage key. **Content opacity.** All data stored via Hubert is obfuscated using ChaCha20 with an ARID-derived key. The stored bytes are indistinguishable from uniform random data. Without the ARID, observers cannot determine whether stored data is a Hubert message, random noise, or any other binary content. Pattern analysis, magic-byte detection, and content scanning all fail. **Payload confidentiality.** Even if an attacker obtains the ARID and reverses the obfuscation, they encounter a GSTP-format Gordian Envelope. The envelope's subject is encrypted with an ephemeral ChaCha20-Poly1305 content key, encapsulated to each recipient's public key. Reading the plaintext requires compromising at least one recipient's private encapsulation key. Knowing the ARID alone is never sufficient. **Sender authentication.** The encrypted GSTP messages are signed with the sender's private signing key. Recipients can verify the message originated from the claimed sender and has not been modified. **Local state minimization.** GSTP implements Encrypted State Continuations (ESC) to minimize local state storage. When a sender needs to preserve private context across a request-response cycle, they encrypt this state to their own public key and embed it as a *sender continuation* in the outgoing message. The recipient cannot decrypt this continuation and must return it unaltered in their response. This pattern is valuable for horizontally-scaled services and resource-constrained devices: the sender's state "travels with the message" rather than accumulating in local storage. ### 3.2 What Hubert Does Not Protect **ARID distribution.** ARIDs must be shared out-of-band before communication begins. A compromised sharing channel lets attackers monitor those locations. * *Mitigations:* Future protocols could derive shared ARIDs from exchanged public keys (similar to X3DH in Signal). **IP address exposure.** Participating in DHT or IPFS networks exposes your IP address to peers you interact with. During a Kademlia lookup on Mainline DHT, you contact roughly 60 distinct nodes. Any can log your IP, the storage key you queried, and the timestamp. The probability that at least one node is logging depends on attacker coverage: | Attacker nodes | Fraction of DHT | Probability observed | | :------------- | :-------------- | :------------------- | | 200,000 | 1% | ~45% | | 20,000 | 0.1% | ~6% | | 2,000 | 0.01% | ~0.6% | With millions of concurrent DHT nodes, even well-resourced attackers operate a small fraction. For untargeted surveillance, observation probability is low. Targeted Sybil attacks require knowing the ARID or derived key in advance, and since ARIDs are random and stored data appears as uniform random bytes, there is no way to identify "interesting" keys by inspecting traffic. **Polling amplification.** When waiting for a message, Hubert polls repeatedly (once per second by default), giving logging nodes multiple observations of the same (IP, key) association. IPFS partially mitigates this through Kubo's local cache, which serves repeated resolutions without additional DHT queries. **Timing patterns.** Even without content, an observer who sees your IP query a key at a particular time learns that association. * *Mitigations*: Route DHT traffic through VPN or Tor (shifting trust). Use exponential backoff and query batching. Add cover traffic. Hubert does not implement these; users requiring IP-level anonymity must layer such protections themselves. **Protocol fingerprinting.** Stored content appears as uniform random bytes, but uniformity itself could be distinguishing. An observer analyzing DHT values might flag high-entropy blobs with no recognizable structure as potential obfuscated messages. This is a fundamental limitation of steganography-by-obfuscation. * *Mitigations:* Plausible cover formats (fake image payloads, torrent metadata) could help but add complexity. **Network-level blocking.** Some regimes block P2P protocols entirely. China's [Great Firewall](https://en.wikipedia.org/wiki/Great_Firewall) uses deep packet inspection, IP blacklisting, and DNS poisoning to block BitTorrent traffic. Similar restrictions exist in Iran, Russia, and other countries with extensive censorship infrastructure. * *Mitigations:* Protocol obfuscation techniques (like Tor's pluggable transports) could disguise traffic as innocuous HTTPS. The local server backend provides a fallback but sacrifices decentralization. Circumventing nation-state network controls is a hard problem that Hubert inherits rather than solves. ### 3.3 No Forward Secrecy Hubert messages are inherently short-lived (see persistence values in Section 2.2). This ephemerality limits the window during which stored data can be retrieved, reducing long-term exposure. However, this is not forward secrecy in the cryptographic sense: if an attacker records the obfuscated blob and later obtains the ARID and a recipient's private key, they can decrypt the message. True forward secrecy would require session keys not derivable from long-term keys, which XID documents do not currently provide. * **Mitigations.** Integrating a ratcheting key agreement protocol (such as Double Ratchet) into GSTP would provide forward secrecy: each message would use a unique ephemeral key, and compromising a later key would not reveal earlier messages. This requires per-session state, conflicting with the stateless dead-drop model, but could be layered above Hubert for long-running conversations. ## 4. Reference Implementation The [`hubert`](https://crates.io/crates/hubert) Rust crate offers a reference implementation, providing both a library for embedding in applications and a command-line tool for scripting and exploration. * **Crate documentation:** [docs.rs/hubert](https://docs.rs/hubert) * **Source repository:** [github.com/BlockchainCommons/hubert-rust](https://github.com/BlockchainCommons/hubert-rust) ### 4.1 Library API The library exposes a single `KvStore` trait that abstracts over all storage backends: ```rust pub trait KvStore: Send + Sync { async fn put(&self, arid: &ARID, envelope: &Envelope, ttl: Option<u64>, pin: bool) -> Result<()>; async fn get(&self, arid: &ARID, timeout: Duration) -> Result<Envelope>; async fn exists(&self, arid: &ARID) -> Result<bool>; async fn check_available(&self) -> Result<()>; } ``` Four implementations are provided: | Type | Module | Use Case | | :---------------------- | :----------------- | :------------------------------------ | | `MainlineDhtKv` | `hubert::mainline` | Fast, lightweight DHT storage (≤1 KB) | | `IpfsKv` | `hubert::ipfs` | Large capacity storage (up to ~10 MB) | | `HybridKv` | `hubert::hybrid` | Automatic size-based routing | | `MemoryKv` / `SqliteKv` | `hubert::server` | Local server backends for testing | All backends enforce write-once semantics: `put` fails with `Error::AlreadyExists` if the ARID has been written. The `get` method polls until the value appears or the timeout expires. The `ttl` parameter controls IPNS record lifetime or server-side retention; `pin` requests IPFS pinning for persistence. ### 4.2 Command-Line Tool The `hubert` binary provides subcommands for all storage operations: * `hubert server [OPTIONS]` — start the local HTTP server * `hubert check [OPTIONS]` — verify backend availability * `hubert generate arid` — generate a fresh ARID * `hubert generate envelope <SIZE>` — generate a test envelope with random data * `hubert put [OPTIONS] <ARID> <ENVELOPE>` — put an envelope at an ARID * `hubert get [OPTIONS] <ARID>` — retrieve from an ARID Storage backend selection via `--storage` [OPTION]: - `mainline` (default): BitTorrent Mainline DHT - `ipfs`: IPFS via local Kubo daemon - `hybrid`: Automatic size-based routing - `server`: Local HTTP server Examples: ```bash # Store a small envelope in the DHT hubert put "$ARID" "$ENVELOPE" # Store a large envelope in IPFS with pinning hubert put --storage ipfs --pin "$ARID" "$ENVELOPE" # Retrieve with 60-second timeout hubert get --timeout 60 "$ARID" # Start a persistent local server hubert server --sqlite ./hubert.sqlite --port 45678 ``` All ARID and Envelope arguments use [UR encoding](https://github.com/BlockchainCommons/research/blob/master/papers/bcr-2020-005-ur.md) (`ur:arid/...` and `ur:envelope/...`). ### 4.3 Error Handling The library uses a single `Error` enum covering all failure modes: | Error | Meaning | |-------|---------| | `AlreadyExists` | Write-once constraint violated | | `NotFound` | Value not present (after timeout) | | `ValueTooLarge` | Exceeds backend capacity | | `StorageBackendUnavailable` | Cannot reach DHT, IPFS, or server | | `InvalidEnvelope` | Deobfuscated data is not a valid Envelope | | `Timeout` | Operation exceeded time limit | The CLI exits with non-zero status on errors and prints diagnostics to stderr. Use `--verbose` for detailed logging of network operations. ## 5. Use Case: FROST Threshold Signing The [`frost-hubert`](https://github.com/BlockchainCommons/frost-hubert-rust) crate coordinates FROST threshold signature ceremonies without a centralized server. * **Crate documentation:** [docs.rs/frost-hubert](https://docs.rs/frost-hubert) * **Source:** [github.com/BlockchainCommons/frost-hubert-rust](https://github.com/BlockchainCommons/frost-hubert-rust) ### 5.1 Overview FROST allows a group of *n* participants to generate a shared public key such that any *t* of them can collaboratively produce a valid Schnorr signature. The resulting signature is indistinguishable from one produced by a single signer. No participant ever possesses the complete private key. The protocol requires multiple rounds. Distributed Key Generation (DKG) takes out-of-band preparation, two rounds of communication, and finalization to establish key shares. Signing takes two rounds plus finalization to produce a threshold signature. Using `frost-hubert`, participants publish encrypted messages to ARID-addressed dead-drops, enabling asynchronous, serverless communication for both DKG and signing ceremonies. ### 5.2 FROST over Hubert Protocol Phases **Phase 1: Registry Setup.** Participants exchange XID Documents out-of-band (Signal, QR codes, etc.) to establish mutual knowledge of public keys. Each maintains a local registry. Hubert is not involved in this phase. **Phase 2: Distributed Key Generation.** A coordinator orchestrates three rounds of message exchange. The coordinator role is administrative, not privileged; they never access other participants' private key shares. | Round | Coordinator Action | Participant Action | |-------|-------------------|-------------------| | 1 | Posts `dkgInvite` with group parameters | Fetches invite, posts commitment | | 2 | Aggregates commitments, sends to each | Verifies, posts secret shares | | 3 | Sends finalize packages | Derives key package | At completion, each participant holds their private signing share and the group's public verifying key. **Phase 3: Signing.** Coordinator posts `signInvite` with the target envelope. Participants post commitments, then signature shares. Coordinator aggregates into a final Schnorr signature. Only *t* participants need respond. ```mermaid sequenceDiagram participant H as Hubert actor C as Coordinator actor P as Participants C->>H: Invite (multicast) H->>P: Invite P->>H: Round 1 responses H->>C: Collected responses C->>H: Round 2 requests H->>P: Round 2 P->>H: Round 2 responses H->>C: Collected responses C->>H: Finalize H->>P: Complete ``` ### 5.3 Operational Notes Participants need not be online simultaneously. Any participant with a complete registry can coordinate a ceremony. The `frost` CLI maintains per-group state in JSON files, surviving process restarts. ## 6. Future Backends Hubert's abstraction layer is intentionally transport-agnostic, enabling future deployments to integrate additional channels as modular backends. ### 6.1 Backend Models Current backends (DHT, IPFS, local server) share a common operational model: sender generates an ARID and derives a storage location, writes the message there, and recipients query for the value at that location. This is the **query-addressable** model. Many promising communication substrates operate differently. Satellite broadcasts, mesh radio networks, and HF transmissions flood messages to all participants; there is no "location" to query. Recipients must monitor the stream and filter for messages obfuscated by keys derived from their ARIDs. This is the **broadcast-filter** model. | Property | Query-Addressable | Broadcast-Filter | | :----------------- | :------------------------------------------ | :---------------------------------------------- | | Recipient liveness | Query at any time within persistence window | Must be online during transmission (or use proxy) | | Sender cost | Single write; network handles storage | Repeated transmissions until TTL expires | | Persistence | Stored on distributed nodes | "Persistence" means repeated broadcast | Both models preserve the ARID-as-capability model and the same security properties. The difference lies in persistence and liveness assumptions. ### 6.2 Candidate Technologies #### 6.2.1 Query-Addressable Technologies **Blockchain inscriptions.** The ARID derives a Bitcoin address; the sender creates a transaction with the payload in OP_RETURN data. Recipients query any blockchain indexer for transactions involving the derived address. Write-once semantics are inherent (blockchain is append-only). Persistence is perpetual. Capacity is limited (~80 bytes for OP_RETURN), suitable for references to content stored elsewhere. Suits high-value, low-frequency coordination where persistence and tamper-evidence outweigh cost and latency concerns. **Physical media.** USB drives and NFC tags allow storage of files named by ARID-derived identifiers. Require physical-layer protocols outside Hubert's network abstraction. #### 6.2.2 Broadcast-Filter Technologies **HF radio.** If the recipient is not listening when the message transmits, it is gone. Coordination requires scheduled transmission windows and recipient discipline. Provides truly global reach. **QR codes.** QR codes must be displayed when recipient is present. Like physical media, requires new physical-layer protocols. **LoRa mesh networks.** Messages flood across ad-hoc mesh topologies. A Hubert backend would interpret `put` as injecting a message with hop-limited flooding and `get` as filtering local mesh traffic for a matching ARID. Excels in disaster-recovery, rural, or maritime scenarios where participants must coordinate without infrastructure. **Satellite broadcast.** Senders pay to inject messages into the broadcast stream; recipients monitor and filter for messages matching their ARIDs. Transmission is costly and one-way, but reception is free, anonymous, and requires no return path. Suits scenarios where recipients must remain entirely passive, unable to emit any RF signature. --- ## Appendix A: Tech Terminology | Term | Category | Definition | |------|------------|-----------| | **ARID** | BC | Apparently Random Identifier: a 256-bit statistically random string that points to an object while revealing nothing about the object or its participants. | | **BEP-44** | BitTorrent | BitTorrent Enhancement Proposal 44: defines mutable items for DHT, addressed by cryptographic public key rather than content hash. | | **CID** | IPFS | Content Identifier: a hash of content that serves as its address. | | **dCBOR** | BC | Deterministic CBOR: a canonical encoding ensuring identical byte representations for identical data. | | **DHT** | BitTorrent | Distributed Hash Table: a decentralized key-value storage system. The BitTorrent Mainline DHT stores small values (≤1 KB). | | **FROST** | | Flexible Round-Optimized Schnorr Threshold signatures: a protocol for generating threshold Schnorr signatures with minimal communication rounds. | | **GSTP** | BC | Gordian Sealed Transport Protocol: provides end-to-end encryption and authentication for messages. | | **HKDF** | | HMAC-based Key Derivation Function: derives cryptographic keys from input keying material. | | **IPFS** | IPFS | InterPlanetary File System: a peer-to-peer distributed file system using content-addressed storage. | | **IPNS** | IPFS | InterPlanetary Name System: provides mutable addresses for IPFS content. | | **XID Document** | BC | eXtensible Identifier Document: a Gordian Envelope structure binding a 32-byte identifier to public keys, permissions, endpoints, and delegation rules. See [BCR-2024-010](bcr-2024-010-xid.md). | ## Appendix B: Tradecraft Terminology | Term | Definition | |------|------------| | **Dead Drop** | A pre-arranged location where one party leaves material for another to retrieve without meeting. Hubert implements this digitally. | **Gray Man** | The principle of blending in to avoid detection. In Hubert, messages appear as random noise indistinguishable from other network traffic. |