Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bachelor Thesis Repository

This repository contains the code for the bachelor thesis "Privacy-Preserving Malicious Email Detection and Filtering with Zero-Knowledge Proofs".

It implements proof-carrying classification for end-to-end encrypted email. A sender can attach a zero-knowledge proof that a body-level spam policy holds without decryption, and the proof is tied to the ciphertext bundle produced by the in-circuit encryption. The repo includes a Python pipeline that trains and evaluates multinomial naive Bayes, linear SVM, and XGBoost models, called GBDT in the thesis, and then quantizes them for in-circuit inference. The export step writes integer model artifacts into Noir constants. On the circuit side, there are Noir implementations for shared feature extraction, inference, and a wrapper that combines classification with ECIES-style encryption. The repo also includes a small UI for generating and verifying proofs. Separate tooling covers benchmarking and analysis.

At the time of writing, the demo UI is hosted at:

Where to look

  • In-Circuit Spam Filter Design:
    • Noir feature extraction + inference circuits: circuits/noir/classifier_infer/
    • Python training/evaluation/export: packages/spam-classifier-pipeline/
    • Generated Noir model constants (from the export step): circuits/noir/classifier_infer/src/consts.nr
  • Cryptographic Construction:
    • Noir ECIES + tag construction: circuits/noir/ecies/
    • Combined circuit (classification + encryption): circuits/noir/spam-encryption/
    • TS counterparts used by the demo UI: packages/ecies-zk-ts/, packages/poseidon-ts/
  • Proof-of-Concept Application: apps/demo-ui/
  • Evaluation / Benchmarking:
    • Classifier evaluation is done in the training pipeline: packages/spam-classifier-pipeline/
    • Performance benchmark runner + reporting: tools/zkp-bench/
    • Circuit variant generator (policy/project variants): circuits/noir/spam-encryption/build.py
  • Thesis documents:
    • Final thesis: documents/thesis/
    • Concept paper: documents/concept-paper/
    • Introduction presentation: documents/intro-presentation/ (live view, navigable with arrow keys)
    • Intermediate presentation: documents/inter-presentation/ (live view, navigable with arrow keys)
    • Final presentation: documents/final-presentation/ (live view, navigable with arrow keys)
  • Datasets live under data/.
  • attic/ contains archived experiments that are not part of the canonical workflow

Keystream alternatives (not covered in the thesis)

The thesis and the default circuit variants use the Poseidon-based keystream. This repository also includes gmimc and hydra keystream variants, which are not discussed in the thesis, but can be selected as optional alternatives.

Repository layout

  • apps/demo-ui/ - Proof-of-concept UI (SvelteKit) + Tauri wrapper
  • packages/spam-classifier-pipeline/ - Python training/eval/calibration/export pipeline
  • packages/ecies-zk-ts/, packages/poseidon-ts/, packages/gmimc-ts/, packages/hydra-ts/ - TS crypto libs for UI (Poseidon is the thesis default; GMiMC/Hydra are optional alternatives)
  • circuits/noir/classifier_infer/ - Noir NB/SVM/XGB inference circuit (GBDT in the thesis terminology)
  • circuits/noir/spam-encryption/ - Noir classifier+encryption wrapper circuit
  • circuits/noir/ecies/ - Noir ECIES library
  • circuits/noir/hydra/ - Noir Hydra library; based on TaceoLabs/noir-hydra v0.4.0, with a small local fix so it compiles against the targeted Noir version
  • tools/zkp-bench/ - Benchmark runner and TCR summary tooling
  • documents/ - Thesis material and the documents that were presented
  • attic/ - Archived/unused experiments and prototypes kept for reference only (not part of canonical reproduction workflow)
  • data/ - Datasets
    • data/enron/enron_spam_data.csv
    • data/artificial-email/email_dataset.csv

Repo tooling (uv + bun)

Convention: command blocks in READMEs assume the current working directory is the directory that contains the README file.

This repo uses:

  • uv for Python environments and locked dependencies
  • bun for TypeScript packages and the demo UI

Alternatively, Python modules can be executed with python in an activated virtualenv and Node tooling (npm/pnpm/yarn) can be used instead of bun.

Toolchain (Noir + bb)

Versions used in this repo:

  • nargo: 1.0.0-beta.12
  • noirc: 1.0.0-beta.12+9a5b3695b42e391fa27c48e87b9bbb07523d664d
  • bb: 0.84.0

Install Noir (pinned):

  • curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
  • noirup -v 1.0.0-beta.12

Install Barretenberg bb (pinned):

  • curl -L https://raw.githubusercontent.com/AztecProtocol/aztec-packages/refs/heads/next/barretenberg/bbup/install | bash
  • bbup -v 0.84.0

Verify:

  • nargo --version
  • bb --version

Canonical workflow

1) Train models (default config)

cd packages/spam-classifier-pipeline
uv sync
uv run -m email_spam_pipeline train --with-meta --models all --config email_spam_pipeline/configs/default.json

Outputs:

  • packages/spam-classifier-pipeline/artifacts_combine_enron/: trained artifacts for NB/SVM/XGB (notably *_int_model.json and *_calibration.json; plus optional stack_meta_*.json when --with-meta is enabled).
  • packages/spam-classifier-pipeline/artifacts_combine_enron_no_ratio/: dedicated no-ratio SVM/XGB variants used by no-ratio circuit variants.

To also export XGB decision tree visualizations as PNGs, enable tree plots in the config:

cd packages/spam-classifier-pipeline
uv sync
uv run -m email_spam_pipeline train --with-meta --models all --config email_spam_pipeline/configs/default.json \
  --set xgb.enable_tree_plots=true \
  --set xgb.tree_plot_format="png" \
  --set xgb.tree_plot_limit=20

PNG files are written to packages/spam-classifier-pipeline/artifacts_combine_enron/tree_plots/ (and to the sibling no-ratio directory when the no-ratio variant is trained).

Or train models on the artificial dataset with a dedicated output folder:

cd packages/spam-classifier-pipeline
uv sync
uv run -m email_spam_pipeline train --with-meta --models all --config email_spam_pipeline/configs/default.json \
  --set dataset.csv="../../data/artificial-email/email_dataset.csv" \
  --set svm.out_dir="artifacts_combine_artificial" \
  --set nb.out_dir="artifacts_combine_artificial" \
  --set xgb.out_dir="artifacts_combine_artificial" \
  --set meta.out_dir="artifacts_combine_artificial" \
  --set calibrate.out_dir="artifacts_combine_artificial"

This writes artifacts to packages/spam-classifier-pipeline/artifacts_combine_artificial/ and the sibling directory packages/spam-classifier-pipeline/artifacts_combine_artificial_no_ratio/.

2) Export consts for Noir inference

cd packages/spam-classifier-pipeline
uv run -m email_spam_pipeline export-consts-combined \
  --nb artifacts_combine_enron/nb_int_model.json \
  --svm artifacts_combine_enron/svm_int_model.json \
  --xgb artifacts_combine_enron/xgb_int_model.json \
  --out ../../circuits/noir/classifier_infer/src/consts.nr

This consumes the quantized integer model artifacts (*_int_model.json) from step 1 and exports them as an auto-generated Noir source file (circuits/noir/classifier_infer/src/consts.nr) that is compiled into the Noir inference circuits.

Or for artifacts trained on the artificial dataset:

cd packages/spam-classifier-pipeline
uv run -m email_spam_pipeline export-consts-combined \
  --nb artifacts_combine_artificial/nb_int_model.json \
  --svm artifacts_combine_artificial/svm_int_model.json \
  --xgb artifacts_combine_artificial/xgb_int_model.json \
  --svm-no-ratio artifacts_combine_artificial_no_ratio/svm_int_model.json \
  --xgb-no-ratio artifacts_combine_artificial_no_ratio/xgb_int_model.json \
  --out ../../circuits/noir/classifier_infer/src/consts.nr

3) Generate policy/project variants

The policy variants are compiled circuits used for the proof-of-concept application, while the project variants are used for performance benchmarking.

cd circuits/noir/spam-encryption
uv run build.py --artifacts policies
uv run build.py --artifacts projects

Generated outputs:

  • Policy JSONs (for the demo UI): circuits/noir/spam-encryption/output/policies.json and circuits/noir/spam-encryption/output/policy/*.json (these embed the compiled circuit ABI + bytecode for each variant).
  • Project variants (for benchmarking): circuits/noir/spam-encryption/output/projects/*.

To use freshly generated policies in the demo UI, copy them into apps/demo-ui/static/:

cp circuits/noir/spam-encryption/output/policies.json apps/demo-ui/static/policies.json
mkdir -p apps/demo-ui/static/policy
cp circuits/noir/spam-encryption/output/policy/*.json apps/demo-ui/static/policy/

For artifacts trained on the artificial dataset:

cd circuits/noir/spam-encryption
uv run build.py --artifacts policies \
  --model-artifacts-dir ../../../packages/spam-classifier-pipeline/artifacts_combine_artificial \
  --model-artifacts-no-ratio-dir ../../../packages/spam-classifier-pipeline/artifacts_combine_artificial_no_ratio
uv run build.py --artifacts projects \
  --model-artifacts-dir ../../../packages/spam-classifier-pipeline/artifacts_combine_artificial \
  --model-artifacts-no-ratio-dir ../../../packages/spam-classifier-pipeline/artifacts_combine_artificial_no_ratio

Bench tooling

cd tools/zkp-bench
uv sync
uv run zkp-bench --help
uv run zkp-tcr-summary --help

Demo UI (optional)

cd apps/demo-ui
bun install
bun run dev

Docker smoke test (works-on-my-machine)

Verify the main commands in a smoke runner in a Docker container.

docker build -t smoke-test .
docker run --rm smoke-test

About

Privacy-preserving email filtering with Zero-Knowledge Proofs, including thesis, evaluation code, and Noir/Barretenberg proof-of-concept components

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

Contributors

Languages