Skip to content

Instantly share code, notes, and snippets.

@m0wer
m0wer / wabisabi_tor_timing.md
Created July 9, 2026 17:38
Tor guard-fingerprint timing attack on WabiSabi

Tor guard-fingerprint timing attack on WabiSabi: measured on real Tor

TL;DR. A plaintext observer of a WabiSabi round (the coordinator, its TLS-terminating CDN, or the VPS behind it) sees per-request timing. Tor pins each client to a long-lived guard, so that client's circuits share a near-constant latency offset — a fingerprint that re-links a round's anonymous outputs to its known inputs. On the live Tor network (8 guards, tor 0.4.9.8) the offset is real but small next to per-request jitter (build: 167 ms offset vs 461 ms jitter; guard RTT 23 vs 56 ms), so a single request barely beats chance — but that is a best case, measured from one fiber host: it omits

@m0wer
m0wer / wabisabi_tagging.md
Created July 9, 2026 16:33
WabiSabi Round ID tagging: a working PoC

WabiSabi Round ID tagging: a working PoC

TL;DR. WabiSabi (Wasabi 2.0) uses keyed-verification anonymous credentials (KVACs) over secp256k1, but unlinkability rests on key consistency: every participant must be issued credentials under the same issuer parameters, committed in the Round ID. The client never checks this. The Round ID is whatever the coordinator returns to that client's own status poll, and a light client cannot independently verify other participants' ownership proofs (the coordinator supplies the very scriptPubKey they are checked against). So a malicious coordinator hands each

@m0wer
m0wer / whirlpool_tagging.md
Last active July 9, 2026 12:54
Whirlpool blind-signing-key tagging: a working PoC

Whirlpool blind-signing-key tagging: a working PoC

TL;DR. Whirlpool's (Samourai) input/output unlinkability rests on a Chaumian RSA blind signature. The client accepts the RSA public key from whatever the coordinator pushes to it each round and never checks that every participant got the same key. A malicious coordinator can hand each of the five inputs a different keypair; every unblinded output signature then verifies under exactly one of them, so the coordinator reads the input -> output mapping straight off the output registrations. Swapping one shared key for one key per input turns a full 5-of-5 anonymity set into five

Making JoinMarket makers harder to follow

TL;DR. JoinMarket market makers reuse the same coins across many CoinJoins, and what they leave behind (change outputs with predictable values, respent round after round) lets a patient chain analyst cluster a maker's history for free, passively, from public chain data. We spent a while researching and prototyping ways out, and this writeup collects what we found. Everything below is demonstrated with real transactions on Bitcoin signet:

  1. Makers should also be Lightning swap providers. No protocol change at
@m0wer
m0wer / copilot-quota.sh
Last active April 16, 2026 14:46
Github Copilot subscription quota tracker
#!/usr/bin/env bash
# copilot-quota.sh — Shell function to check GitHub Copilot premium request quota
#
# Installation:
# Copy this file somewhere, e.g. ~/.config/opencode/copilot-quota.sh
# Then add to your ~/.bashrc or ~/.zshrc:
# source ~/.config/opencode/copilot-quota.sh
#
# Usage:
# copilot-quota
@m0wer
m0wer / calblockers.py
Created January 8, 2026 08:14
Create privacy blockers across multiple calendars
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Calendar Blockers - Create privacy blockers across multiple calendars
This script automatically creates "blocker" events on target calendars for every
event found in source calendars. The blocker events only show a generic title
(e.g., "private" or "busy") without revealing actual event details, helping
maintain privacy when sharing calendars.
@m0wer
m0wer / fidelity_bond_exponent_analysis.py
Created January 5, 2026 10:27
JoinMarket Fidelity Bond Exponent Analysis
"""
JoinMarket Fidelity Bond Exponent Analysis
Using real orderbook data to evaluate Sybil attack scenarios
"""
import numpy as np
import pandas as pd
from dataclasses import dataclass
from typing import List
import plotly.graph_objects as go
@m0wer
m0wer / fiat2sats.user.js
Created May 6, 2025 13:47
Fiat to Sats Converter Greasemonkey user script
// ==UserScript==
// @name Fiat to Sats Converter
// @namespace https://gist.github.com/m0wer/
// @version 1.4
// @license MIT
// @description Converts fiat currency prices (USD, EUR) to Bitcoin satoshis
// @author m0wer
// @match *://*/*
// @grant GM.xmlHttpRequest
// @grant GM_info
@m0wer
m0wer / mercadona_wh.sh
Created October 28, 2024 16:27
Obtain Mercadona warehouses
curl -O https://raw.githubusercontent.com/inigoflores/ds-codigos-postales-ine-es/refs/heads/master/data/codigos_postales_municipios.csv
tail -n +2 codigos_postales_municipios.csv | \
cut -d',' -f1 | \
sort -u | \
while read code; do \
curl -s -H 'Content-Type: application/json' \
-d "{\"new_postal_code\": $code}" \
-D - \
https://tienda.mercadona.es/api/postal-codes/actions/change-pc/ \
| grep -i "x-customer-wh" \
@m0wer
m0wer / px_bug_datetime_tz.ipynb
Created March 25, 2020 12:45
Plotly express bug pandas datetime with timezone
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.