Taprootized Atomic Swaps
Taprootized Atomic Swaps (TAS) is an extension for Atomic Swaps that presumes the untraceability of transactions related to a particular swap. Based on Schnorr signatures, Taproot technology, and zero-knowledge proofs, the taprootized atomic swaps hide swap transactions under regular payments.
Atomic swap is an incredible approach to cross-chain exchanges without mediators. However, one of the disadvantages of its implementation in the classical form is the “digital trail” — any party can make a matching between transactions in the blockchains in which the exchange took place and find out both the participants in the exchange and the proportion in which assets were exchanged.

On the other hand, atomic swaps is a technology that initially assumed the involvement of only two parties and a “mathematical contract” between them directly. That is, an ideal exchange presupposes 2 conditions: 1) Only counterparties participate in the exchange (works by default) 2) Only counterparties know about the fact of the exchange (it would be nice to ensure)
This paper will provide a concept of taprootized atomic swaps that allow hiding the swap's very fact. To an external auditor, transactions to initiate and execute atomic swaps will be indistinguishable from regular Bitcoin payments. In the other accounting system involved in the transfer, more information is disclosed (the fact of exchange can be traced). Still, it is impossible to link this to the corresponding Bitcoin transactions (without additional context from the involved parties).

skA, PKA) and Bob (skB, PKB) have their keypairs and know each other's public keys.k and calculates the public value K = k * GScript = sig(skA) + Locktime in the form of Bitcoin Script PKEsc = K + PKB + hash((K + PKB) || Script) * G (here,
escrow is just a public key, formed using Taproot technologysig(skEsc), verified by thr PKEsc, can be generated only with the knowledge of k, skB and Scripth as a hash value of k (zk-friendly hash function is recommended to use)skEsc: Bob, with knowledge of k and skB can spend the outputskA + Locktime: Alice, with knowledge of skA can spend the output, but only after some point in time t1 (it's the Script itself)proof that includes:k that satisfies k * G == Kk that satisfies zkHash(k) == hhKScriptproofPKEsc as K + PKB + hash((K + PKB) || Script) * G and finds the transaction locked BTC (verifies it exists). Then Bob performs the following verification:k that satisfies k*G == K and zkHash(k) == h, it means that Bob can access the output PKEsc if he receives kScript is correct and includes only the required alternative path.k and the signature of skA: only Alice can spend it if she reveals k (hash preimage)skB + Locktime: Bob, with knowledge of skB, can spend the output, but only after some point in time t2zkHash())k together with the signature generated by her skA. As a result - Alice spent funds locked by Bob.k, Bob can return funds after locktime is reachedk, Bob can recognize it and extract the k valueskEsc as skEsc = k + skB + hash((K + PKB) || Script)skEsc and spends funds locked by Alice.Transactions: 1. Alice locks BTC: 850e9258bf8b3bb280d32a647198d8024aece543dc283f7bfa526f4c0ceb1ab8 2. Bob locks ETH: 723919c0e8ec57d38792ec29b2cb82ee885b9fbbc886b34ff40fb5d3f7cc9b43 3. Alice withdraws ETH from the contract: 47546191a7c99ec4a7ddc243d6ea75d345ab3aff0762e09dd2f537731bd484f3 4. Bob spends BTC: 859dbfaa901d7106aecc8cb29966ede0c9d7a17c2cae31f4d420c1d770e9706d
This repository provides all components for executing an atomic swap, including a script for an Ethereum-Bitcoin exchange between Alice and Bob.
circuits: Contains Circom circuits for Zero-Knowledge proof
creation in step eight of the outlined flow. These circuits verify the knowledge of a private
256-bit scalar k, where K = k * G and h = Poseidon(k), with K and h being public,
Poseidon being the hash function, and G representing the Secp256k1 base point.contracts: Contains the Depositor contract in Solidity designed for depositing
native currency using a 256-bit number h and locktime, locking funds with two withdrawal
conditions:k that h = Poseidon(k)- money goes to the message senderlocktime has passed - money goes to the deposit makercrates: Contains Rust crates for ZkSnark witness, proof generation, and validation. Proof
generation currently takes about 13 seconds on an M1 Pro chip, with witness calculation
accounting for 10 seconds. Utilizing c++ bindings instead of the existing wasm witness
calculator can notably reduce this time.src: Contains the Rust script for facilitating an atomic swap between Alice and Bob. It
encompasses all steps outlined in the documentation, including proof generation, taproot
transaction creation, and executing transactions on both Bitcoin and Ethereum networks.scripts: Contains auxiliary scripts for Circom and SnarkJS.You can use either testnets for Ethereum and Bitcoin networks or run the local test networks by
using such utilities as ganache for Ethereum and
nigiri for Bitcoin.
You can use this deployed, verified and ready for use contracts:
- Ethereum mainnet: 0x936f971455bc674F77312f451963681fe964E838
- Sepolia testnet: 0x85BEaB7f80B375175BeCC3f68Bf86d33099fD576
You can use trusted setup files (.ptau, at least 17th power) from [SnarkJs] repository, you
can find it in the readme section, for ZK proof generation.
Cargo,
Circom,
SnarkJSconfig.toml. Check the config.example.toml for example, it has detailed description.cargo install):
bash
cargo run config.tomlBefore compiling make sure, that you have the OpenMP installed on your device. It is required
dependency to build the rapidsnark-sys crate.
sudo apt update sudo apt upgrade
sudo apt install libomp-dev
We use a circom ecdsa implementation from 0xPARC.
$ claude mcp add taprootized-atomic-swaps \
-- python -m otcore.mcp_server <graph>