Skip to content

Investigate circuit padding support (maybenot) #50

@igor53627

Description

@igor53627

Overview

Arti 1.8.0 adds experimental circuit padding support via the maybenot library to resist traffic fingerprinting attacks.

Parent issue: #49


Investigation Findings

WASM Compatibility: [PASS]

maybenot is WASM-compatible:

  • Pure Rust library, no native/OS bindings
  • Dependencies (rand, flate2, serde, etc.) all work on wasm32
  • Runtime-agnostic design (consumes events, returns actions - no I/O or threads)
  • Used by Mullvad VPN in production

Architecture in tor-proto

Circuit padding is behind feature flags:

  • circ-padding - Core maybenot integration
  • circ-padding-manual - Manual machine configuration API

Key types:

  • PaddingController - Reports traffic events to padding machines
  • PaddingEventStream - Produces padding/blocking actions
  • CircuitPadderConfig - Machine configuration (optional)

Current state:

  • webtor-rs uses vendored tor-proto WITHOUT circ-padding
  • Uses no_padding.rs (no-op implementation)
  • Circuit reactor already has the API wiring in place

Recommended Approach

Stage 0: Receive-only Tolerance (Minimal, Low Risk)

Effort: S (<1h)

Modify no_padding.rs to drop unexpected padding cells instead of erroring:

pub(crate) fn decrypted_padding(&self, _hop: HopNum) -> Result<(), crate::Error> {
    // Treat unexpected padding as ignorable instead of fatal
    Ok(())
}

Benefits:

  • No new dependencies
  • No bandwidth overhead
  • Compatible with future Tor padding behavior
  • Zero risk

Stage 1: Full maybenot Integration (Opt-in)

Effort: M (1-3h)

  1. Add feature flag to webtor:
[features]
circ-padding = ["tor-proto/circ-padding"]
  1. Keep disabled by default (bandwidth concerns for WASM)

  2. Use upstream default CircuitPadderConfig (no custom tuning)

  3. Test on wasm32-unknown-unknown + browser


Performance/Bandwidth Implications

CPU/Memory

  • Minor overhead (small state machines)
  • Per-circuit state: few KB
  • Well within existing Tor crypto budget

Bandwidth (Main Concern for WASM)

  • Extra Tor cells + possible delays
  • Users often on metered/mobile connections
  • Web sockets incur overhead per frame
  • This is why full padding should be opt-in

Decision: Recommended Path

  1. Default for webtor-rs: Receive-only tolerance (Stage 0)

    • Minimal change to no_padding.rs
    • Compatible with future Tor behavior
    • No bandwidth impact
  2. Optional advanced mode: Full padding (Stage 1)

    • Behind feature flag, disabled by default
    • For privacy-focused users who accept bandwidth cost
    • Measure overhead before promoting to default

Tasks

Stage 0 (Recommended)

  • Modify vendor/arti/crates/tor-proto/src/client/circuit/padding/no_padding.rs
  • Change decrypted_padding to return Ok(()) instead of error
  • Test: no crashes when network sends padding

Stage 1 (Optional, Future)

  • Add circ-padding feature flag to webtor
  • Enable tor-proto/circ-padding behind the flag
  • Test WASM compilation with feature enabled
  • Measure bandwidth overhead
  • Document user-facing toggle

Related Files

  • vendor/arti/crates/tor-proto/Cargo.toml - Feature flags
  • vendor/arti/crates/tor-proto/src/client/circuit/padding/no_padding.rs - Stage 0 change
  • vendor/arti/crates/tor-proto/src/client/circuit/padding/maybenot_padding.rs - Full impl
  • webtor/src/circuit.rs - Circuit management

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions