惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
量子位
A
Arctic Wolf
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
V
Vulnerabilities – Threatpost
博客园 - Franky
C
Cyber Attacks, Cyber Crime and Cyber Security
The Cloudflare Blog
Last Week in AI
Last Week in AI
The Hacker News
The Hacker News
I
Intezer
J
Java Code Geeks
P
Privacy International News Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Secure Thoughts
Cisco Talos Blog
Cisco Talos Blog
阮一峰的网络日志
阮一峰的网络日志
S
Securelist
Security Latest
Security Latest
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
小众软件
小众软件
Jina AI
Jina AI
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
博客园_首页
酷 壳 – CoolShell
酷 壳 – CoolShell
T
The Exploit Database - CXSecurity.com
雷峰网
雷峰网
T
Tenable Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy & Cybersecurity Law Blog
Simon Willison's Weblog
Simon Willison's Weblog
博客园 - 【当耐特】
T
Threat Research - Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
K
Kaspersky official blog
H
Help Net Security
宝玉的分享
宝玉的分享
罗磊的独立博客
Webroot Blog
Webroot Blog
月光博客
月光博客
B
Blog RSS Feed
Recorded Future
Recorded Future

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Frequency Hopping Spread Spectrum on LoRa SX1262: Making Radio Undetectable
autoAbode · 2026-04-28 · via DEV Community

LoRa is a remarkable modulation scheme. It achieves sensitivity below -140 dBm, delivers reliable links at distances conventional radios cannot reach, and does it all at milliwatt power levels. But LoRa has a weakness that is rarely discussed in maker communities: a standard LoRa transmission is trivially detectable.

A fixed-frequency LoRa signal shows up on any spectrum analyser or SDR waterfall display as a distinctive chirp pattern. Its centre frequency, bandwidth, and spreading factor can be identified in seconds. For many applications this does not matter. For some, it matters enormously.

This article describes how we implemented frequency hopping spread spectrum on the Semtech SX1262 to build a radio link that is resistant to detection, interception, and jamming. This is the core RF technology behind MeshVani Relay, our long-range encrypted relay module.

Why Fixed-Frequency LoRa Is Detectable

To understand the solution, you need to understand the problem. A standard LoRa transmission has several characteristics that make it easy to find:

Predictable centre frequency. Most LoRa devices operate on one of a handful of ISM band channels. In India, that means 865 to 867 MHz. A scanner only needs to monitor a 2 MHz window.

Long dwell time. LoRa achieves its range by spreading each symbol over a long period. At SF12 with 125 kHz bandwidth, a single symbol takes 32.77 milliseconds. A complete packet can occupy the channel for several seconds. That is an eternity for a spectrum monitoring system.

Distinctive chirp signature. LoRa uses CSS (chirp spread spectrum), which produces a visually and mathematically distinctive pattern of upchirps and downchirps. Even without decoding the payload, a monitoring system can identify the modulation as LoRa within one symbol period.

Fixed transmission parameters. Most LoRa networks use static SF, bandwidth, and coding rate. Once identified, the signal parameters never change, making it trivial to configure a targeted receiver.

For a tactical communication device, these properties are unacceptable. An adversary with a $30 RTL-SDR dongle and a laptop can detect, locate (via direction finding), and potentially jam a conventional LoRa link.

FHSS: The Concept

Frequency hopping spread spectrum solves this by never staying on one frequency long enough to be characterised. The transmitter and receiver share a pseudorandom hopping sequence that dictates which frequency to use for each time slot. The signal hops across a wide band, spending only a brief moment on each channel.

The key metrics are:

  • Hopping bandwidth: The total spectrum over which the signal hops. Wider is better for detectability resistance.
  • Number of channels: How many discrete frequencies the system hops between.
  • Dwell time: How long the signal remains on each frequency before hopping.
  • Hopping rate: The inverse of dwell time, how many hops per second.

The relationship between these parameters determines the system's LPD (Low Probability of Detection) and LPI (Low Probability of Intercept) characteristics.

Our Implementation: 64 Channels on SX1262

The SX1262 is not designed for FHSS out of the box. Its LoRa modem is optimised for fixed-frequency operation. Implementing FHSS required working around several hardware constraints.

Channel Plan

We define 64 hop channels spread across the available ISM band. Each channel is spaced far enough apart to avoid spectral overlap at our chosen bandwidth:

// Channel plan (pseudocode)
NUM_CHANNELS = 64
BASE_FREQ = 865_000_000        // 865 MHz
CHANNEL_SPACING = 200_000      // 200 kHz spacing
BANDWIDTH = 125_000            // 125 kHz LoRa bandwidth

function get_channel_freq(channel_index):
    return BASE_FREQ + (channel_index * CHANNEL_SPACING)

// Channel 0:  865.0 MHz
// Channel 1:  865.2 MHz
// ...
// Channel 63: 877.6 MHz
// Total hopping bandwidth: 12.6 MHz

Enter fullscreen mode Exit fullscreen mode

The 200 kHz spacing with 125 kHz bandwidth provides 75 kHz of guard band between adjacent channels, sufficient to prevent inter-channel interference even with the SX1262's frequency synthesis tolerance.

Pseudorandom Hopping Sequence

The hopping sequence must be pseudorandom but deterministic, both transmitter and receiver need to agree on which channel to use at each moment. We generate the sequence using AES-256 in counter mode, keyed with the shared session key:

// Hopping sequence generation (pseudocode)
function generate_hop_sequence(session_key, epoch_counter):
    // Generate 64 bytes of pseudorandom data
    prng_block = AES_256_CTR(
        key = session_key,
        nonce = epoch_counter,
        plaintext = zeros(64)
    )

    // Map each byte to a channel index (0-63)
    sequence = []
    for i in 0..63:
        sequence.append(prng_block[i] mod NUM_CHANNELS)

    return sequence  // 64-hop sequence before regeneration

Enter fullscreen mode Exit fullscreen mode

Using the encryption key to drive the hopping sequence means that an adversary who does not possess the key cannot predict the next hop frequency, even if they observe the current one. The hopping pattern is cryptographically random from an external observer's perspective.

Timing Synchronisation

FHSS requires tight time synchronisation between transmitter and receiver. If they are not on the same channel at the same time, the link fails. We use a two-phase synchronisation approach:

Phase 1: Beacon. The relay module periodically transmits a synchronisation beacon on a known rendezvous channel. This beacon contains a timestamp and the current position in the hopping sequence. New nodes listen on the rendezvous channel until they hear a beacon, then synchronise their local clock.

Phase 2: Drift correction. Once synchronised, each received packet serves as a timing reference. We measure the time-of-arrival against the expected hop schedule and apply a correction factor. The ESP32-S3's 32.768 kHz RTC crystal drifts at approximately 20 ppm, which gives us about 1.2 milliseconds of drift per minute. Our hop dwell time is 50 milliseconds, with a 5-millisecond guard interval, so the timing budget allows roughly 4 minutes between correction events.

// Hop timing (pseudocode)
HOP_DWELL_TIME_MS = 50      // Time on each channel
GUARD_INTERVAL_MS = 5        // Rx/Tx turnaround margin
EFFECTIVE_HOP_RATE = 1000 / (HOP_DWELL_TIME_MS + GUARD_INTERVAL_MS)
// = 18.18 hops per second

function current_channel(base_time, hop_sequence):
    elapsed_ms = now() - base_time
    hop_index = (elapsed_ms / (HOP_DWELL_TIME_MS + GUARD_INTERVAL_MS)) mod 64
    return hop_sequence[hop_index]

Enter fullscreen mode Exit fullscreen mode

Channel Change Latency

The SX1262 requires approximately 100 microseconds to change frequency via the SetRfFrequency command. This is well within our 5 ms guard interval. However, we found that the PLL settling time varies with the frequency step size. Large jumps (more than 5 MHz) occasionally required up to 250 microseconds. We pre-sort the hopping sequence to avoid the largest jumps where possible, without compromising the cryptographic randomness of the overall pattern.

Why Conventional Scanners Fail

A conventional RF scanner or spectrum analyser detects signals by sweeping across a frequency band and measuring energy at each point. Let us examine why this approach fails against our FHSS implementation.

Sweep rate mismatch. A typical spectrum analyser sweeps at a rate determined by its resolution bandwidth and span. For a 12.6 MHz span with 10 kHz RBW, the sweep time is approximately 160 milliseconds. Our signal dwells on each channel for only 50 milliseconds. By the time the analyser sweeps past a channel, the signal has already hopped away. The analyser sees noise.

Energy spreading. Even if a wideband receiver captures the entire 12.6 MHz band simultaneously, the signal energy is distributed across 64 channels. The energy on any single channel is 18 dB below the total transmitted energy (10 * log10(64) = 18.06 dB). At our transmit power levels, this puts the per-channel energy below the noise floor of most monitoring equipment at tactically relevant distances.

No persistent signature. Direction-finding systems typically require multiple samples on the same frequency to compute a bearing. With 18 hops per second, the signal never stays still long enough for conventional DF algorithms to converge.

Per-Hop Encryption

FHSS provides detection resistance, but it does not provide confidentiality on its own. A sufficiently wideband receiver could, in theory, capture all channels simultaneously and reconstruct the transmission. To guard against this, every hop carries its own AES-256-GCM encrypted payload.

Each hop's encryption uses a nonce derived from the hop index and a session counter, ensuring that even if an adversary captures and correlates multiple hops, the content remains encrypted with a unique nonce per hop:

// Per-hop encryption (pseudocode)
function encrypt_hop_payload(data, session_key, hop_index, session_counter):
    nonce = build_nonce(hop_index, session_counter)
    ciphertext, tag = AES_256_GCM(
        key = session_key,
        nonce = nonce,
        plaintext = data,
        aad = hop_index.to_bytes()   // Bind ciphertext to specific hop
    )
    return ciphertext || tag

Enter fullscreen mode Exit fullscreen mode

The hop index is included as authenticated additional data (AAD), which binds each encrypted fragment to its specific position in the hopping sequence. Replaying a captured fragment on a different hop index causes the GCM authentication to fail.

Performance Characteristics

The MeshVani Relay achieves the following measured performance with FHSS enabled:

  • Range: 20 km line-of-sight (measured at 1.2 kbps effective throughput)
  • Effective data rate: 1.2 to 4.8 kbps depending on SF selection per hop
  • Latency: 55 to 110 ms per hop (dwell time plus guard interval plus processing)
  • Hopping rate: 18.18 hops/second
  • LPI figure of merit: Approximately -24 dB relative to a fixed-frequency transmission at the same total power

The throughput reduction compared to fixed-frequency LoRa is roughly 30%, which is the cost of the guard intervals and frequency settling time. For the applications where FHSS matters, this trade-off is more than acceptable.

Practical Considerations

Regulatory compliance. FHSS in the ISM band is permitted under most regulatory frameworks, including India's WPC rules, provided the hopping bandwidth and dwell time meet specific thresholds. Our 64-channel, 12.6 MHz implementation comfortably exceeds the minimum requirements.

Temperature effects. The SX1262's crystal oscillator drifts with temperature, which can cause the actual transmit frequency to deviate from the commanded frequency. At temperature extremes, this drift can push the signal partially outside the intended channel bandwidth. We compensate by reading the ESP32-S3's on-board temperature sensor and applying a correction table derived from factory characterisation of each crystal.

Multipath and fading. Because each hop uses a different frequency, multipath nulls that affect one channel do not affect the next. FHSS provides inherent frequency diversity, which improves link reliability in environments with reflections and obstructions. In urban testing, we measured a 6 dB improvement in effective link margin compared to fixed-frequency operation on the worst-case channel.

Conclusion

FHSS on the SX1262 is not a simple feature toggle. It requires careful coordination of timing, cryptographic sequence generation, and RF management. But the result is a radio link that is dramatically harder to detect, intercept, or jam than a conventional LoRa transmission.

The principles described here are applicable to any SX1262-based design where RF security is a concern. The specific implementation in MeshVani Relay adds the AES-256-GCM encryption layer and the mesh network integration that tie it all together into a deployable system.

Details on the full relay module are at autoabode.com/meshrelay.


Shubham Garg is the Founder and Managing Director of AutoAbode, a New Delhi-based company building secure communication hardware, industrial 3D printers, and autonomous platforms since 2015.