Not private. Bitcoin is a fully transparent ledger. The Pedersen commitment in the vote proof
hides your choice from a passive observer of the JSON, but the blinding value is revealed to the tally and the
on-chain footprint links each vote to a public key. This is authenticated voting, not anonymous voting.
For anonymous voting you need a shielded pool (Zcash, Monero) or a Chaumian ecash layer.
Read first. Experimental prototype. Generates unsigned Bitcoin transaction templates
(Bitcoin Core RPC commands) and cryptographic vote proofs. Holds no keys, connects to no network, broadcasts
nothing. No external dependencies — secp256k1, BIP-340 Schnorr, bech32, and the multisig script
builder are all implemented inline so this file works offline and inside strict CSP sandboxes.
Self-test
Loading…
1 · Voter Keypair
Each voter generates a secp256k1 keypair locally. The public key is x-only (BIP-340). The
secret never leaves this page.
No key generated.
2 · Multisig Pool (P2WSH)
Enter the compressed public keys of the pool's cosigners and a threshold. The tool builds the
witness script, computes the P2WSH address, and generates the funding commands. No key sharing
required — this is real script-enforced multisig, not Shamir.
3 · Proposal
4 · Cast a Vote
A vote is a BIP-340 Schnorr signature over (proposalId ‖ choice ‖ nullifier), plus a Pedersen
commitment to the choice. The nullifier is deterministic from the voter's public key and the proposal, so
the tally can enforce one-vote-per-key without any registration step.
5 · Tally (off-chain)
Paste one vote-proof JSON per line, or a JSON array. The tally verifies each BIP-340 signature,
recomputes the nullifier from the public key, rejects duplicates, and verifies the Pedersen commitment.
6 · Transaction Builder (PSBT)
Produces Bitcoin Core RPC commands for funding the pool, casting a vote (anti-spam payment),
and spending via the multisig. These are templates — review against your node's
documentation before running.
7 · Air-gapped PSBT Signing Workflow
Cold machine: generate the cosigner keys offline. Write the secret keys
on paper. Never connect this machine to a network.
Online coordinator: collect the compressed public keys from each cosigner,
build the witness script + P2WSH address in §2, and share the address with funders.
Funders: send BTC to the P2WSH address. Verify the address matches the
expected witness script independently.
To spend: build an unsigned PSBT with createpsbt. Transfer the
PSBT file to each cosigner over USB.
Each cosigner: run walletprocesspsbt on the cold machine to
add their signature. Return the updated PSBT to the coordinator.
Coordinator: once K signatures are collected, run
finalizepsbt and broadcast with sendrawtransaction.
Reality check. Bitcoin's P2WSH multisig is script-enforced — this is strictly stronger
than the Shamir workaround on chains without native multisig. But the witness script must be published to
the funders before they send BTC: a P2WSH address is a hash of the script, and sending to the wrong
script hash means the coins are unspendable forever. Distribute the address and the script together and
have each funder independently verify sha256(script) → bech32.
8 · Local Audit Log
Everything you generate is logged locally in localStorage. Nothing leaves this
browser. Export as JSON for independent verification.