比特幣隱私技術進階應用指南

深入介紹 CoinJoin、PayJoin 進階應用,以及 Taproot 帶來的隱私增強與最佳實踐。

比特幣隱私技術進階應用指南

比特幣的區塊鏈是公開的,但用戶可以透過各種技術手段提升交易隱私。本篇文章深入介紹比特幣隱私保護的高級技術,包括 CoinJoin、PayJoin 的進階應用、Taproot 帶來的隱私增強,以及 Schnorr 簽名批次驗證的技術細節。我們將從協議規範、實際操作、程式碼範例等多個維度進行全面解析。

比特幣隱私的基本概念

比特幣交易涉及以下可被觀察的資訊:

提升隱私的目標是打破這些資訊之間的關聯性,使外部觀察者難以確定交易的真正發送者和接收者。

區塊鏈分析的 基本假設

區塊鏈分析公司通常依賴以下假設進行交易追蹤:

  1. 同一輸入假設(Common Input Heuristic):假設交易的所有輸入都屬於同一個所有者。這是比特幣錢包設計的常見模式,但也是 PayJoin 刻意打破的弱點。
  1. 金額 round number 假設:整數或 near-round 金額的交易可能表明是餘額轉移而非消費。
  1. 時間模式假設:相同時間或規律時間發送的交易可能來自同一實體控制的多個地址。

理解這些假設是設計隱私策略的基礎。

CoinJoin 進階應用

什麼是 CoinJoin

CoinJoin 是一種將多個用戶的交易合併到單一交易中的技術,使外部觀察者難以確定輸入和輸出的對應關係。其核心原理是:當多個用戶同時創建一筆包含各自輸入和輸出的交易時,區塊鏈上只顯示所有輸入和所有輸出,無法確定哪個輸入對應哪個輸出。

CoinJoin 的數學原理

假設有 n 個用戶參與 CoinJoin,每個用戶提供一個輸入和一個輸出:

輸入:(A1, B1), (A2, B2), ..., (An, Bn)
輸出:(A1', B1'), (A2', B2'), ..., (An', Bn')

外部觀察者看到的是 n 個輸入和 n 個輸出的集合,但無法通過區塊鏈分析確定 (Ai, Bi) 與 (Ai', Bi') 的對應關係。從資訊論角度,這創造了 n! 種可能的對應組合,使得低成本的去匿名化變得不可行。

實現方式

1. 協調者模式

由第三方服務協調多個用戶的交易。這種方式用戶體驗較好,但需要信任協調者不會記錄對應關係或與分析公司合作。

用戶 A → 協調者 ← 用戶 B
    ↓          ↓
 輸入 A      輸入 B
    ↓          ↓
 協調者合併交易
    ↓
 區塊鏈廣播

2. 去中心化模式

用戶直接點對點協作,無需信任第三方。這種方式更安全但技術門檻較高。

知名 CoinJoin 實現

Wasabi Wallet 與 WabiSabi 協議

Wasabi Wallet 採用 WabiSabi 協議,這是一種基於 Chaumian CoinJoin 的改進方案。其特點包括:

WabiSabi 的核心創新是引入了Credential Issuance 機制,用戶無需預先註冊即可參與混合,這解決了早期 CoinJoin 方案的 Sybil 攻擊問題。

// WabiSabi 協議關鍵概念偽代碼
public class WabiSabiRound
{
    // 協調者公開參數
    public BigInteger G;  // 橢圓曲線生成點
    public BigInteger H;  // 第二生成點(用於金額承諾)
    public BigInteger q;  // 曲線階

    // 註冊階段:用戶提交金額承諾
    public Commitment RegisterInput(Guid roundId, BigInteger commitment)
    {
        // C = g^v * h^r,其中 v 是金額,r 是隨機數
        BigInteger r = GenerateRandomNumber();
        BigInteger C = ModPow(G, v, q) * ModPow(H, r, q) % q;
        return new Commitment(C, r);
    }

    // 輸出註冊:用戶提交輸出地址和金額承諾
    public void RegisterOutput(Guid roundId, BitcoinAddress address, BigInteger commitment)
    {
        // 協調者只知道 commitment,不知道實際金額
    }

    // 簽名階段:門檻簽名
    public partialSignature SignRound(Guid roundId, BigInteger userRandom)
    {
        // 每個用戶貢獻一個 partial signature
        // 當收集到足夠數量的 partial signatures 後,組合為最終簽名
    }
}

Samourai Wallet 與 Whirlpool

Whirlpool 是 Samourai Wallet 實現的 CoinJoin 方案,其特點包括:

JoinMarket:流動性提供者模型

JoinMarket 允許用戶選擇作為「Maker」(流動性提供者)賺取費用,或作為「Taker」進行混合。這種經濟激勵機制創造了持續的流動性。

# JoinMarket Maker 角色關鍵邏輯
class JoinMarketMaker:
    def __init__(self, wallet, fee_percentage=0.01):
        self.wallet = wallet
        self.fee_percentage = fee_percentage

    def create_offer(self, amount_sats, coinjoin_amount):
        """
        創建一個 CoinJoin 報價
        amount_sats: 總金額
        coinjoin_amount: 用於 CoinJoin 的金額
        maker_fee: 從 maker 收取的費用
        """
        # 計算費用
        maker_fee = int(coinjoin_amount * self.fee_percentage)

        # 構建交易
        # 輸入: Taker 的輸入 + Maker 的輸入
        # 輸出: Taker 輸出 + Maker 輸出 + 找零

        return {
            'coinjoin_amount': coinjoin_amount,
            'maker_fee': maker_fee,
            'inputs': self.select_inputs(coinjoin_amount + maker_fee),
            'output_script': self.get_change_script()
        }

CoinJoin 實際操作指南

步驟一:環境準備

# 安裝 Wasabi Wallet (Linux)
wget https://github.com/zkSNACKs/WalletWasabi/releases/latest/download/Wasabi-2.0.0.0.deb
sudo dpkg -i Wasabi-2.0.0.0.deb

# 運行 Wasabi
wasabi

步驟二:錢包創建與資金準備

  1. 創建新錢包,妥善保存 seed phrase
  2. 建議使用專門的「混合資金」地址,避免與日常消費資金混用
  3. 初始資金建議小額測試

步驟三:執行 CoinJoin

  1. 選擇「CoinJoin」標籤
  2. 選擇要混合的金額(Wasabi 建議使用 0.1 BTC 以上的金額以獲得最佳隱私)
  3. 選擇匿名集合大小(越大越好,但等待時間更長)
  4. 點擊「Start CoinJoin」

步驟四:驗證混合結果

# 使用 bitcoin-cli 分析交易
# 獲取 CoinJoin 交易詳情
bitcoin-cli getrawtransaction "txid" true

# 檢查輸入數量(正常 CoinJoin 應有多個輸入)
# 檢查輸出金額分佈

CoinJoin 的隱私極限

即使使用 CoinJoin,仍存在以下限制:

  1. 參與者數量:需要足夠的參與者數量才能創造有效的混淆。建議至少 10 個參與者。
  1. 金額洩露:如果參與者選擇特殊金額(如 0.1 BTC),可能通過金額模式分析識別。
  1. 歷史交易模式:即使單次 CoinJoin 成功,歷史交易的時間、金額模式仍可分析。
  1. UTXO 合併:混合後的 UTXO 如果與其他資金合併,可能洩露隱私。

Schnorr 簽名與批次驗證

Schnorr 簽名基礎

Taproot 升級引入的 Schnorr 簽名是比特幣密碼學的重大進步。與 ECDSA 相比,Schnorr 簽名具有以下優勢:

Schnorr 簽名演算法

Schnorr 簽名的核心公式如下:

選取隨機數 k
計算 R = k*G (G 為生成點)
計算 e = Hash(R || m) (m 為消息)
計算 s = k + e*x (x 為私鑰)

簽名 = (R, s)
驗證:s*G = R + e*P (P = x*G 為公鑰)

批次驗證的數學原理

Schnorr 簽名的線性特性允許批次驗證。假設有 n 個簽名 (R₁, s₁), (R₂, s₂), ..., (Rₙ, sₙ),對應消息 m₁, m₂, ..., mₙ:

單獨驗證:
s₁*G = R₁ + e₁*P₁
s₂*G = R₂ + e₂*P₂
...
sₙ*G = Rₙ + eₙ*Pₙ

批次驗證(線性組合):
∑sᵢ*G = ∑Rᵢ + ∑eᵢ*Pᵢ

左側:計算 n 次標量乘法 + 1 次點加法
右側:計算 n 次哈希 + n 次點加法 + n 次點乘

批次驗證的關鍵優化是將 n 個簽名的驗證合併為一次計算,顯著減少密碼學運算次數。根據比特幣核心開發團隊的測試,批次驗證可以將 1000 個簽名的驗證速度提升約 40%。

批次驗證的隱私應用

1. 多簽名聚合

傳統多簽名交易會在區塊鏈上顯示所有公鑰和簽名,Schnorr 聚合後只顯示一個聚合公鑰和一個聚合簽名:

# 多簽名聚合示例
class SchnorrMultisig:
    @staticmethod
    def aggregate_public_keys(public_keys):
        """
        聚合多個公鑰為單一公鑰
        P_agg = P₁ + P₂ + ... + Pₙ
        """
        aggregated = public_keys[0]
        for pk in public_keys[1:]:
            aggregated = aggregated + pk
        return aggregated

    @staticmethod
    def create_aggregate_signature(secret_keys, message):
        """
        創建聚合簽名
        每個參與者生成部分簽名
        s = s₁ + s₂ + ... + sₙ
        """
        partial_signatures = []
        for sk in secret_keys:
            # 每個參與者獨立的隨機數
            k_i = random_scalar()
            R_i = k_i * G

            # 計算挑戰
            e = hash(R_i + message)

            # 部分簽名
            s_i = k_i + e * sk
            partial_signatures.append((R_i, s_i))

        # 聚合 R 和 s
        R_agg = sum(r for r, _ in partial_signatures)
        s_agg = sum(s for _, s in partial_signatures) % N

        return (R_agg, s_agg)

2. 閃電網路隱私增強

閃電網路的通道開啟和關閉交易使用多簽名。通過 Schnorr 聚合:

// 簡化的 Schnorr 聚合簽名驗證(Rust 風格)
fn batch_verify_schnorr(signatures: Vec<SchnorrSignature>, messages: Vec<Message>) -> bool {
    // 隨機線性組合係數
    let mut z = random_scalar();

    // 計算左側:z * s*G
    let mut left = signatures[0].s * G;
    for sig in signatures.iter().skip(1) {
        left = left + (sig.s * G);
    }
    left = left * z;

    // 計算右側:z*R + z*e*P
    let mut right = signatures[0].R;
    for sig in signatures.iter().skip(1) {
        right = right + sig.R;
    }
    right = right * z;

    // 添加挑戰項
    for (i, (sig, msg)) in signatures.iter().zip(messages.iter()).enumerate() {
        let e = hash(sig.R, msg);
        let term = e * sig.public_key * z;
        right = right + term;
    }

    left == right
}

隱私增強效果分析

Schnorr 簽名對隱私的提升表現在多個層面:

特性ECDSA 多簽名Schnorr 聚合
鏈上顯示n 個公鑰 + n 個簽名1 個聚合公鑰 + 1 個簽名
簽名大小64n 字節64 字節
驗證次數n 次1 次
隱私程度低(可識別多簽名)高(外觀與單簽名相同)

PayJoin 詳解

什麼是 PayJoin

PayJoin(也稱為 Pay-to-Endpoint)是比特幣隱私技術的重要進展,它允許交易的發送者和接收者共同創建一筆交易,使雙方的輸入和輸出混合。這種技術的核心優勢是打破「所有輸入屬於同一所有者」的假設。

PayJoin 的運作流程

步驟 1:協商階段
  發送者 → 接收者:我想支付 1 BTC
  接收者 → 發送者:好的,請在我的輸出中加入 0.5 BTC

步驟 2:構建交易
  發送者輸入:2 BTC
  接收者輸入:0.5 BTC

  輸出 1:發送者找零 1 BTC
  輸出 2:接收者實際收款 1 BTC
  輸出 3:接收者額外輸出 0.5 BTC(來自接收者輸入)

步驟 3:簽名與廣播
  雙方分別簽名自己的輸入
  共同廣播交易

BIP-78 規範

PayJoin 的標準化規範為 BIP-78,主要包含以下內容:

<!-- PayJoin 請求示例 -->
GET /?amount=1.0&pj=%2Fpayjoin&memo=Payment%20for%20order%20%23123 HTTP/1.1
Host: merchant.com
Accept: application/json

<!-- 接收者響應 -->
{
    "outputs": [
        {"amount": 100000000, "script": "..."},
        {"amount": 50000000, "script": "..."}  // 接收者輸出
    ],
    "inputs": [
        {"txid": "...", "vout": 0, "witness": "..."}
    ],
    "fee": 1000
}

PayJoin 的隱私優勢

  1. 打破假設:傳統區塊鏈分析假設交易的所有輸入都屬於同一人。PayJoin 打破這一假設,接收者的輸入證明雙方都有資金投入。
  1. 金額混淆:交易中包含雙方的資金,使輸出金額難以對應到具體用戶。即使分析師識別出 PayJoin 交易,也無法確定哪個輸出屬於哪一方。
  1. 雙向混淆:PayJoin 交易甚至可以實現資金的雙向流動,使外部觀察者無法確定誰是真正的發送方或接收方。

PayJoin 實現要求

支持 PayJoin 的錢包

Taproot 隱私優勢

Taproot 升級帶來的改變

2021 年 11 月激活的 Taproot 升級為比特幣帶來了顯著的隱私改進:

  1. 腳本類型統一:所有 Taproot 交易在外觀上相同,無論其複雜程度如何。
  1. MAST 結構:只揭示實際執行的腳本路徑,未使用的條件保持隱藏。這允許複雜的腳本設置(如時間鎖、多簽名條件)而不會在區塊鏈上暴露所有可能性。
  1. Schnorr 簽名:多簽名交易與單簽名交易外觀相同,提供前述的批次驗證和聚合能力。

MAST 技術細節

MAST(Merkelized Abstract Syntax Tree)將可能的解鎖條件組織為 Merkle 樹:

        Root
       /    \
    [A]      [B,C]
   /  \     /    \
  A   B    C    D

當執行條件 A 時,只需展示:

條件 B、C、D 的存在及其詳細內容被隱藏。這極大地擴展了比特幣的智慧合約能力,同時保持區塊鏈隱私。

Taproot 隱私應用場景

  1. 多簽名錢包:所有參與者的簽名聚合後與普通交易無異
  1. 時間鎖合約:只在時間到期時才揭示腳本條件
  1. Lightning Network:通道開啟和關閉變得更加隱密
  1. 遺囑/繼承合約:預設條件隱藏,只有在特定事件發生時才揭示

隱私增強的實際效果

假設用戶 A 向用戶 B 支付比特幣:

隱私最佳實踐

1. 地址重用避免

每次交易使用新地址是基本的隱私保護原則。現代比特幣錢包默認支援 BIP-47 隱藏地址或一次性地址。

# BIP-47 隱藏地址生成邏輯
class BIP47PaymentCode:
    def __init__(self, payment_code):
        self.payment_code = payment_code  # 256-bit 編碼的 payment code

    def generate_address(self, index):
        """
        從 payment code 生成第 index 個隱藏地址
        發送方和接收方獨立地計算相同地址
        """
        # 計算共享密鑰
        shared_secret = self.payment_code * self.private_key
        shared_point = shared_secret.point  #  elliptic curve point

        # 計算子密鑰
        child_key = derive_child_key(shared_point, index)

        # 生成 P2PKH 地址
        pubkey = child_key.public_key
        address = hash160(pubkey)

        return address_to_base58(address)

2. 交易金額切割

避免整數金額(如 1.00000000 BTC),可選擇隨機金額使區塊鏈分析更困難。

# 金額切割示例
# 原始金額:1.0 BTC
# 分割為多個隨機金額:
# 0.23456789 BTC -> 輸出給接收者
# 0.76543211 BTC -> 回到自己的找零地址

3. 節點連接隱私

# Bitcoin Core 配置隱私節點連接
bitcoin.conf:

# 強制使用 Tor
proxy=127.0.0.1:9050
onion=127.0.0.1:9050
listen=1
bind=127.0.0.1

# 避免泄露 IP
dnsseed=0
addnode=node.bitcoin.i2p

4. 錢包選擇

5. 時間間隔策略

避免在短時間內進行多筆關聯交易。區塊鏈分析會使用時間聚類分析識別同一實體控制的地址。

# 交易時間間隔建議
class PrivacyTimingStrategy:
    # 最小等待時間(小時)基於金額
    MIN_WAIT_HOURS = {
        'small': 4,      # < 0.1 BTC
        'medium': 24,    # 0.1 - 1 BTC
        'large': 168,    # > 1 BTC (一週)
    }

    @staticmethod
    def calculate_wait_time(amount_sats):
        if amount_sats < 10_000_000:
            return PrivacyTimingStrategy.MIN_WAIT_HOURS['small']
        elif amount_sats < 100_000_000:
            return PrivacyTimingStrategy.MIN_WAIT_HOURS['medium']
        else:
            return PrivacyTimingStrategy.MIN_WAIT_HOURS['large']

隱私技術的限制

區塊鏈分析技術

區塊鏈分析公司使用多種技術進行交易追蹤:

隱私與便利性的權衡

更強的隱私通常意味著:

實際隱私級別評估

隱私級別技術手段交易費用複雜度適用場景
基礎每次新地址日常消費
中等錢包 CoinJoin一般隱私需求
專業混幣服務大額交易
最高多層混合 + Tor很高很高敏感交易

結論

比特幣隱私是一個持續發展的領域。Taproot 升級、PayJoin 協議的採用、Schnorr 簽名的批次驗證能力,以及更多隱私保護錢包的出現,都在不斷提升比特幣用戶的隱私保護能力。選擇適合自己需求的隱私級別,並理解不同技術的優劣,是每個比特幣用戶應該掌握的知識。

重要的是,隱私不是絕對的,而是相對的。即使無法達到完美的隱私,採用適當的技術手段也能大幅提高攻擊成本,使大規模監控變得不可行。比特幣的隱私保護是一場持續的軍備競賽,隨著技術的進步,用戶將擁有更多保護自身財務隱私的工具。


相關主題

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!