Skip to content

IFM Frequency Model ​

Overview ​

A frequency in IFM is a human-friendly namespace that maps to a 256-bit network identifier (Topic ID). This separation allows the protocol to evolve beyond the FM radio metaphor while maintaining backward compatibility.


Frequency Representation ​

Human-Friendly Frequency ​

91.700
chat.general
music.lofi
weather.tokyo
sensor.greenhouse.3
game.room.42
private.team
team.alpha

Canonical Identifier ​

ifm://public/91.700
ifm://public/chat.general
ifm://public/music.lofi
ifm://public/weather.tokyo
ifm://public/sensor.greenhouse.3
ifm://public/game.room.42
ifm://protected/private.team
ifm://hidden/team.alpha

Network Identifier (Topic ID) ​

BLAKE3("ifm://public/91.700")        = 0xabcdef...
BLAKE3("ifm://public/chat.general")  = 0x123456...
BLAKE3("ifm://protected/private.team") = 0x789abc...
BLAKE3("ifm://hidden/team.alpha")    = 0xfedcba...

Frequency Structure ​

rust
struct Frequency {
    namespace: Namespace,    // public | protected | hidden
    channel: String,         // human-readable channel name
    version: u8,             // protocol version for this frequency
}

Namespace Types ​

NamespacePrefixEncryptionDiscoveryUse Case
Publicifm://public/None (plaintext)DHT + GossipSubOpen broadcast, chat, streaming
Protectedifm://protected/ChaCha20-Poly1305DHT + GossipSub (key required to decrypt)Private groups, team comms
Hiddenifm://hidden/ChaCha20-Poly1305Invite-only (not in DHT)Secret channels, secure comms

Frequency Resolution ​

Parsing Human Frequency ​

Resolution Algorithm ​

rust
fn resolve_frequency(input: &str) -> Result<Frequency> {
    // 1. Try parsing as canonical URI
    if input.starts_with("ifm://") {
        return parse_canonical(input);
    }
    
    // 2. Check for explicit namespace prefixes
    if input.starts_with("public:") {
        return Ok(Frequency { namespace: Public, channel: input[7..].into(), version: 1 });
    }
    if input.starts_with("protected:") || input.starts_with("private:") {
        return Ok(Frequency { namespace: Protected, channel: input.split(':').nth(1).unwrap().into(), version: 1 });
    }
    if input.starts_with("hidden:") {
        return Ok(Frequency { namespace: Hidden, channel: input[7..].into(), version: 1 });
    }
    
    // 3. Heuristic: FM-like frequencies (digits + optional dot)
    if input.chars().all(|c| c.is_ascii_digit() || c == '.') {
        return Ok(Frequency { namespace: Public, channel: input.into(), version: 1 });
    }
    
    // 4. Default: public namespace
    Ok(Frequency { namespace: Public, channel: input.into(), version: 1 })
}

Frequency Hash (Topic ID) ​

rust
fn frequency_to_topic_id(freq: &Frequency) -> [u8; 32] {
    let canonical = freq.to_canonical_string(); // e.g., "ifm://public/91.700"
    BLAKE3::hash(canonical.as_bytes()).into()
}

Properties:

  • Deterministic: same frequency always → same Topic ID
  • Uniform distribution: suitable for DHT keyspace
  • 256-bit: collision-resistant
  • Used as: GossipSub topic, DHT key, cache key

Frequency Metadata ​

Optional metadata attached to frequencies (broadcast via ANNOUNCE packets):

rust
struct FrequencyMetadata {
    name: Option<String>,           // "General Chat"
    description: Option<String>,    // "Main discussion channel"
    language: Option<String>,       // "en", "es", "ja"
    encryption: EncryptionType,     // None | ChaCha20Poly1305
    listener_count: u32,            // Current peers tuned in
    capabilities: Vec<Capability>,  // Voice, Chat, File, Video, etc.
    created_at: u64,                // Unix timestamp
    owner: Option<PeerId>,          // For protected/hidden frequencies
}

Capabilities ​

CapabilityDescription
voiceReal-time voice communication
chatText messaging
videoVideo streaming
fileFile transfer
telemetryIoT sensor data
gamingMultiplayer game sync
aiAI agent communication

Frequency Operations ​

Tune (Join Frequency) ​

Leave Frequency ​

1. GossipSub: UNSUBSCRIBE from Topic ID
2. Send LEAVE packet (optional, graceful)
3. Close frequency-specific connections
4. Clean up local state, emit "left" event

Scan (Discover Frequencies) ​

1. DHT: Iterate known frequency announcements
2. Local: mDNS/UDP multicast for LAN frequencies
3. Return list of (Frequency, Metadata, PeerCount)

Protected Frequencies ​

Key Derivation ​

Encryption ​

  • Algorithm: ChaCha20-Poly1305 (AEAD)
  • Nonce: 12-byte prefix + 4-byte packet sequence (big-endian)
  • AAD: Canonical frequency string
  • Applied: At packet payload level (before signing)
rust
fn encrypt_payload(payload: &[u8], key: &[u8; 32], nonce_prefix: &[u8; 12], sequence: u64, aad: &[u8]) -> Vec<u8> {
    let mut nonce = [0u8; 12];
    nonce[..8].copy_from_slice(nonce_prefix);
    nonce[8..].copy_from_slice(&sequence.to_be_bytes());
    
    chacha20_poly1305_encrypt(key, &nonce, payload, aad)
}

Hidden Frequencies ​

  • Not advertised in DHT
  • Not announced via ANNOUNCE packets
  • Joined only via direct invitation (QR code, secure link, out-of-band)
  • Same encryption as protected frequencies
  • Topic ID still derived from canonical form (but canonical form never published)

Frequency Naming Conventions ​

Public Frequencies ​

PatternExampleUse Case
FM-style91.700, 88.5, 107.9Radio-like broadcast
Category.namechat.general, music.lofi, news.worldOrganized channels
Location.categoryweather.tokyo, traffic.la, alerts.sfGeo-specific
Sensor.typesensor.temperature, sensor.humidityIoT telemetry

Protected Frequencies ​

PatternExampleUse Case
private.nameprivate.team, private.familyPrivate groups
org.nameacme.engineering, acme.salesOrganization channels
project.nameproject.alpha, project.launchProject rooms

Hidden Frequencies ​

PatternExampleUse Case
secret.namesecret.op, secret.meetingCovert comms
game.room.idgame.room.42, game.lobby.7Game sessions
device.iddevice.camera.1, device.drone.3Device control

Frequency Lifecycle ​


Mermaid: Frequency Resolution Flow ​


Examples ​

Public Frequency ​

json
{
  "human": "91.700",
  "canonical": "ifm://public/91.700",
  "topic_id": "0xabcdef1234567890...",
  "encryption": "none",
  "discoverable": true
}

Protected Frequency ​

json
{
  "human": "private.team",
  "canonical": "ifm://protected/team",
  "topic_id": "0x1234567890abcdef...",
  "encryption": "ChaCha20-Poly1305",
  "discoverable": true,
  "key_required": true
}

Hidden Frequency ​

json
{
  "human": "team.alpha",
  "canonical": "ifm://hidden/team.alpha",
  "topic_id": "0xfedcba0987654321...",
  "encryption": "ChaCha20-Poly1305",
  "discoverable": false,
  "invite_only": true
}

Custom Canonical Form ​

json
{
  "human": "ifm://protected/acme.engineering",
  "canonical": "ifm://protected/acme.engineering",
  "topic_id": "0x9988776655443322...",
  "encryption": "ChaCha20-Poly1305",
  "discoverable": true
}

Released under the MIT License.