As I keep studying this, I'm finding a lot of interesting things. In outline, you can prove that you own a public key by providing a signature on an agreed message, and that the key is one of a set of ~ 100 million (merkle tree depth 26 say, though it matters little if you vary between 20-30); you hash the pubkey using Poseidon, which is particularly friendly to zkps because it only requires a few hundred constraints in the circuit. Then for the signature, you use ECDSA - a fascinating detail here (I'm not sure if anyone considered this), is that because BIP340Schnorr uses key-prefixing you can't make the message hash ("e") be a *public* input to the circuit (that SHA2 hash would have to be calculated in zero knowledge, which is a lot more expensive than Poseidon), whereas with ECDSA, by a trivial algebraic manipulation, you can convert the verification to a form like a*B + C = D, where the nonce-point R and the msghash are public inputs. It's still a significant expense, because you're doing (only 1) curve addition and multiplication, but with the use of secq as the base field, and with some fairly basic optimizations, it ends up being reasonable. For this case, I am getting about a 16kB size proof and about 1.5 seconds of verification time *using javascript/wasm, not rust or C*, and, on a laptop. Considering that is for a proof of, easily, the anon set of the *entire utxo set of bitcoin*, then at least in theory, this is a very impressive achievement.