Chaff's logo, the effect of chaff on the display of a Würzburg Riese radar, edited to form a "C".
Original image source.
Chaff is a website fingerprinting (WF) defence framework inspired by Maybenot1 and the Tor circuit padding framework2. What sets Chaff apart (and makes it experimental) is it's use of priority queues. The circuit padding framework is based on Finite State Machines (FSMs), Maybenot is based on extended FSMs (with counters and timers), and Chaff uses a form of queue machine.
The reason why Chaff is experimental is because it is unproven. Chaff hasn't been integrated into any existing privacy-enhancing technologies, it is still missing a host of features that would make it complete, and your mileage may vary. One of the key aims for Chaff was to evaluate if the queue machine model is valid and/or useful for developing safe WF defences.
WF defences often act like countermeasures to detection that confuse a classifier. Chaff is a countermeasure for RADAR that confuses an operator.
This is an ongoing dissertation forming part of my (@peterc-s) degree. No contributions are currently being welcomed. If you are interested in Chaff, wait until around July 2026, when this restriction may be lifted.
Chaff consists of many crates, each serving their own purpose:
chaff- the main framework library. Contains the entrypoint (theFrameworkstruct) into Chaff along with all of its component parts.chaff-sim- the simulator for running Chaff defences on traces.chaff-capture- a basic trace capture library, built on top ofpcapwhich is in turn built on top oflibpcap.chaff-datasets- parsers for different WF papers' datasets.chaff-machines- defences implemented in Chaff.chaff-cli- a basic CLI for using the various Chaff features.
See their respective README.mds and documentation for specific usage.
For reproducible builds, Chaff uses nix. A flake.nix is provided with all the development tools needed and a couple of development shells.
If you just want to build Chaff, you can run:
nix buildThe resulting artefacts will be put in result/.
If you don't want to use Nix, you can use cargo directly, but you may need external libraries such as libpcap:
cargo build --releaseTo use the command line:
cargo run --release -- --helpTo install:
cargo install --path ./crates/chaff-cli/
# then
chaff-cli --helpFor development purposes, you might want to enter the default development shell:
nix developYou can now use cargo to build Chaff just like any other Rust project.
To check changes before making a PR, you can run:
nix flake checkWhich is what the CI/CD pipeline does.
Note
CI/CD can still fail even if nix flake check passes locally. This usually happens if the flake inputs are out of date (run nix flake update) or if Arti has bumped their MSRV.
Chaff uses aggressive clippy lints and should compile with -Wpedantic. It also aims for 100% coverage via cargo-tarpaulin using the LLVM backend. There are some false positives, currently they are not being ignored with attributes: if code changes within the scope of the attribute and is no longer covered, you couldn't tell.
By convention, datasets should go in data/. See chaff-datasets and chaff-sim for information on acquiring the Tik-Tok dataset.