— design principle behind Hedy Lamarr's frequency-hopping patent, 1942">
Classroom Glossary Public page

RF-201 Week 3 — Frequency Hopping + Spread Spectrum: FHSS, DSSS, and Chirp

1,338 words

"The most effective defense against a jammer is to move faster than it can follow." — design principle behind Hedy Lamarr's frequency-hopping patent, 1942


Lecture (90 min)

3.1 Why Spread Spectrum?

WIR-101 mentioned spread spectrum in the context of Bluetooth's FHSS and 802.11b's DSSS. RF-201 opens the mechanism.

Three reasons spread spectrum was invented:

  1. Anti-jamming: A narrowband jammer covers a small frequency slice. A signal spread across a wide band can lose some of that slice and still be recoverable.
  2. LPI/LPD (Low Probability of Intercept/Detection): A spread signal looks like noise to a receiver that doesn't know the spreading code. The power spectral density drops below the thermal noise floor.
  3. Multiple access: Multiple users can share the same wide band simultaneously if each has a different spreading code that despreading extracts while treating all others as noise (CDMA).

All three motivations are security-relevant. You will encounter them in ZigBee, GPS, military radios, and cellular.

3.2 DSSS: Direct-Sequence Spread Spectrum

Mechanism: Multiply each data bit by a high-rate pseudorandom bit sequence (the "chip sequence" or "spreading code"). The resulting wideband signal occupies a bandwidth equal to the chip rate, not the data rate.

s_DSSS(t) = d(t) · c(t) · cos(2πf_c·t)

where d(t) is the ±1 data stream at rate R_b and c(t) is the ±1 chip sequence at rate R_c (chip rate). The processing gain is R_c / R_b (typically 10-100×).

Despreading: The receiver multiplies the received signal by the same chip sequence c(t) and integrates over one data bit period. Because c(t) · c(t) = 1, the data bit is recovered. Interference from another DSSS user with a different code is rejected: c_1(t) · c_2(t) ≈ 0 for orthogonal codes.

802.11b DSSS: Used 11-chip Barker sequences at 11 Mchip/s to carry 1 Mbps (Barker) or 11 Mbps (CCK). The Barker sequence is chosen for its ideal autocorrelation: a peak at zero lag, low sidelobes at all other lags.

GPS: Uses DSSS with a 1.023 Mchip/s C/A code (coarse acquisition) on L1 (1575.42 MHz). The GPS signal power at the Earth's surface is about -130 dBm — below the thermal noise floor of a wide receiver. Only despreading reveals it. This is the LPI property at work.

Spreading code generation — m-sequences and Gold codes:

A maximal-length sequence (m-sequence) is generated by a linear feedback shift register (LFSR). An n-bit LFSR generates a PN sequence of length 2^n - 1. The autocorrelation of an m-sequence is ideal: +1 at lag 0, -1/(2^n-1) at all other lags.

Gold codes are XOR combinations of two m-sequences with specific offset relationships. They produce near-orthogonal code pairs suitable for CDMA multiple access.

3.3 FHSS: Frequency-Hopping Spread Spectrum

Mechanism: Instead of spreading in bandwidth at one frequency, hop the carrier frequency rapidly across a wide band according to a pseudorandom hopping sequence known to both transmitter and receiver.

f(t) = f_{hop[n]}    for t  [nT_hop, (n+1)T_hop]

Each dwell time T_hop is short. Bluetooth Classic hops 1600 times per second across 79 channels (1 MHz spacing in 2.402-2.480 GHz). In each T_hop = 625 µs slot, Bluetooth uses GFSK to transmit data on one channel.

Slow FHSS: Dwell time ≫ bit period (many bits transmitted per hop). More susceptible to a partial-band jammer that can follow the hop.

Fast FHSS: Dwell time ≤ bit period (multiple hops per bit). More robust against tracking jammers. More complex hardware. Military frequency-hopping radios (HAVE QUICK, SATURN) use fast FHSS.

Bluetooth Classic FHSS in detail:

  • 79 channels numbered 0-78, spaced 1 MHz apart
  • Hop sequence is pseudorandom, derived from the Bluetooth clock and master device address
  • Both devices in a piconet share the same hop sequence (computed independently from shared parameters — no key distribution needed for hopping; the key exchange covers the link-layer encryption)
  • Packet types span 1, 3, or 5 slots; multislot packets freeze the hopper for their duration

Jamming resistance: A narrowband jammer on channel 34 affects only the ~1/79 fraction of packets that land there. With forward error correction and ARQ (automatic repeat request), the effective impact on throughput is minimal.

The security implication: FHSS does not provide confidentiality. A receiver that knows the hop sequence receives every packet. In Bluetooth Classic, the hop sequence is computable from the piconet master's clock and BD_ADDR, which are broadcast in unencrypted inquiry/page packets. You enumerated BD_ADDR in WIR-101 Lab 8. Computing the hop sequence is a solved problem (Ubertooth One tools include bthopper). FHSS was designed for jamming resistance, not confidentiality.

3.4 Chirp Spread Spectrum (CSS): LoRa

Mechanism: A chirp signal is a sinusoid whose instantaneous frequency sweeps linearly over a bandwidth B during a symbol duration T_s.

s_chirp(t) = A · cos(2π(f_0 + k·t)·t)

where k = B/T_s is the chirp rate (Hz/s). An "up-chirp" increases frequency; a "down-chirp" decreases frequency.

LoRa CSS encodes data by cyclically shifting the start frequency of the chirp. For a spreading factor SF, there are 2^SF possible shifts, each corresponding to one symbol value. The base chirp sweeps bandwidth B over 2^SF / B seconds.

The Fourier demodulator: LoRa demodulation is elegant: multiply received by a reference down-chirp (the conjugate of the up-chirp), then take a DFT. The cyclic shift appears as a peak at a specific frequency bin. The bin index is the symbol value. The entire demodulator is one dechirp multiplication + one FFT.

LoRa parameters:

  • Bandwidth (BW): 125/250/500 kHz (EU/US)
  • Spreading Factor (SF): 7-12 (higher SF = more spreading = longer range, lower data rate)
  • Data rate = BW × SF / 2^SF × CR (coding rate)
  • SF=7, BW=125kHz: ~5.5 kbps. SF=12, BW=125kHz: ~293 bps, range 15+ km rural

Processing gain: LoRa at SF=12 has a processing gain of ~20 dB. You can receive a LoRa packet 20 dB below the noise floor if you know what you are looking for.

3.5 Architecture Comparison: FHSS vs. DSSS vs. CSS

Property FHSS (Bluetooth Classic) DSSS (802.11b, GPS) CSS/LoRa
Spreading mechanism Time-domain frequency hops Code-domain multiplication Linear frequency chirp
Instantaneous bandwidth Narrow (1 MHz per hop) Wide (11 MHz for 11 Mbps 802.11b) Medium (125-500 kHz)
Processing gain 79 channels (frequency diversity) 10.4 dB (11 Barker chips) 12-20 dB (SF=7-12)
Primary design goal Jamming resistance; multiple access Multipath tolerance; CDMA sharing Ultra-long range; sub-noise floor
Demodulator complexity PLL + channel switch + GFSK demod PN correlator + integrate-and-dump Dechirp multiply + FFT
LPI property Low (hop seq computable) Medium (below noise floor at GPS power) Medium (looks like noise; wide)

Lab 2: DSSS Transmitter + Receiver in GNU Radio

Duration: 3 hr (in-class + homework)

Deliverable: Working GNU Radio flowgraph implementing a binary DSSS TX/RX pair with an 11-chip Barker sequence. Spectrum screenshot comparing narrowband (unspread) vs. spread signal.

See labs/lab-2.md for full instructions.


Homework

Reading (1.5 hr):

  • Wyglinski Ch 3, §3.4-3.5 (spread spectrum; CDMA)
  • Sklar Ch 12, §12.1-12.3 (direct-sequence spread spectrum) — if available; otherwise PySDR Ch 6 (BER)
  • Review: GNU Radio wiki "Spread Spectrum Tutorial" (free; start from scratch)

Hands-on (1.5 hr): Modify the Lab 2 flowgraph: change the Barker sequence to a random 31-chip m-sequence (LFSR with polynomial x^5 + x^3 + 1). Measure the correlation properties in Python:

import numpy as np
# 31-chip m-sequence from LFSR(5, poly=[5,3,0])
def gen_mseq(n_bits, poly_taps):
    reg = [1] + [0]*(n_bits-1)
    seq = []
    for _ in range(2**n_bits - 1):
        seq.append(reg[-1])
        feedback = sum(reg[t] for t in poly_taps) % 2
        reg = [feedback] + reg[:-1]
    return np.array([1 if b else -1 for b in seq])

mseq = gen_mseq(5, [5,3])
autocorr = np.correlate(mseq, mseq, mode='full')
print('Peak:', autocorr.max(), '  Sidelobe max:', np.abs(autocorr[autocorr != autocorr.max()]).max())

What does this tell you about the m-sequence's performance as a spreading code?


Key Terms

  • Processing gain (PG): improvement in SNR from despreading; PG = chip rate / data rate in DSSS; determines jamming resistance
  • PN sequence: pseudorandom noise sequence; the spreading code; deterministic but statistically random-looking
  • m-sequence (maximal-length sequence): generated by an LFSR; ideal autocorrelation; length 2^n - 1 for n-bit LFSR
  • Gold code: pair of m-sequences XORed together; near-orthogonal; enables CDMA multiple access
  • Chirp rate (k): rate of frequency sweep in CSS; k = B/T_s (Hz/s)
  • Spreading factor (SF): LoRa's bit-depth parameter; 2^SF symbols per chirp; higher SF = more range, lower rate
  • Dechirp: multiply received chirp by conjugate reference chirp; converts cyclic shift to a tone; the first stage of LoRa demodulation
  • LPI/LPD: low probability of intercept/detection; spread signal below thermal noise floor of a wide receiver