以太坊 BLS 簽章密碼學完整實作指南:從數學原理到工程部署

BLS 簽章是以太坊 PoS 共識機制的核心密碼學原語。本文提供完整的 BLS 簽章實作指南,涵蓋金鑰生成、簽章驗證、聚合簽章、批次驗證等核心主題,並提供 py_ecc 等函式庫的實務使用範例。深入分析以太坊共識層密碼學套件的實際運作機制。

以太坊 BLS 簽章密碼學完整實作指南:從數學原理到工程部署

概述

BLS 簽章(Boneh–Lynn–Shacham Signatures)是以太坊權益證明(PoS)共識機制的核心密碼學原語。相較於傳統的 ECDSA 簽章,BLS 簽章支援非互動式簽章聚合特性,使以太坊能夠在數十萬驗證者的規模下實現高效的共識確認。本文從密碼學基礎出發,提供完整的 BLS 簽章實作指南,涵蓋金鑰生成、簽章驗證、聚合簽章、批次驗證等核心主題,並提供以太坊共識層密碼學套件(py_ecc、protolambda 等)的實務使用範例。

一、橢圓曲線密碼學基礎回顧

1.1 BLS 簽章所需的數學結構

BLS 簽章的安全性建立在橢圓曲線配對(Elliptic Curve Pairing)的數學性質之上。以太坊共識層使用以下曲線配置:

BN128 曲線參數

曲線方程式:y² = x³ + 3 (mod p)

質數 p = 21888242871839275222246405745257275088696311157297823662689037894645226208583

曲線階 n = 21888242871839275222246405745257275088548364400416034343698204186575808495617

基點 G 的座標:
  Gx = 1
  Gy = 2

配對友好的群結構:
  - G₁:橢圓曲線上的點,發布在 G1 = (1, 2)
  - G₂:橢圓曲線的某個擴域上的點
  - GT:配對結果群(橢圓曲線的乘法循環群)

1.2 配對運算的數學性質

BLS 簽章依賴於以下關鍵的配對性質:

雙線性映射

e(a × P, b × Q) = e(P, Q)^(ab)

其中:
- P ∈ G₁
- Q ∈ G₂  
- a, b ∈ Z_n(整數)
- e: G₁ × G₂ → GT

這個雙線性性質使得簽章聚合成為可能,因為:

e(σ₁ + σ₂, G) = e(sk₁×H(m) + sk₂×H(m), G)
              = e(H(m), G)^(sk₁ + sk₂)
              = e(H(m), P₁ + P₂)

二、BLS 簽章核心演算法實現

2.1 金鑰生成

金鑰生成是 BLS 簽章系統中最基本的安全原語。必須使用密碼學安全的隨機數生成器(CSPRNG)。

Python 實現

import os
from typing import Tuple
from py_ecc import bn128

class BLSKeyGenerator:
    """BLS 金鑰生成器
    
    以太坊共識層使用 RFC 9380 定義的 Hash-to-Curve 演算法
    將訊息映射到 G₂ 群
    """
    
    G1 = bn128.G1
    G2 = bn128.G2
    n = bn128.curve_order
    
    @classmethod
    def generate_private_key(cls) -> int:
        """生成私鑰:均勻隨機選擇 [1, n-1] 範圍內的整數
        
        安全性要求:
        - 使用 os.urandom() 或同等安全的隨機源
        - 私鑰不能為 0 或 n-1
        """
        while True:
            # 從 256 位隨機字節生成
            random_bytes = os.urandom(32)
            private_key = int.from_bytes(random_bytes, 'big')
            
            # 確保私鑰在有效範圍內
            if 1 <= private_key < cls.n:
                return private_key
    
    @classmethod
    def derive_public_key(cls, private_key: int) -> Tuple[int, int]:
        """從私鑰推導公鑰
        
        公鑰 = private_key × G (在 G₁ 群上)
        
        Args:
            private_key: 私鑰整數
            
        Returns:
            公鑰座標 (x, y)
        """
        return cls.G1.multiply(cls.G1, private_key)
    
    @classmethod
    def keygen(cls) -> Tuple[int, Tuple[int, int]]:
        """完整的金鑰對生成流程
        
        Returns:
            (私鑰, 公鑰) 元組
        """
        sk = cls.generate_private_key()
        pk = cls.derive_public_key(sk)
        return sk, pk

# 使用範例
sk, pk = BLSKeyGenerator.keygen()
print(f"私鑰 (hex): {hex(sk)}")
print(f"公鑰座標: ({hex(pk[0])}, {hex(pk[1])})")

2.2 訊息雜湊到曲線

BLS 簽章需要將任意長度的訊息雜湊到橢圓曲線群 G₂ 上。以太坊使用 RFC 9380 定義的 Hash-to-Curve 演算法。

Hash-to-G2 實現

import hashlib
from py_ecc import bn128
from py_ecc.utils import int_to_bytes, bytes_to_int

class HashToCurve:
    """RFC 9380 Hash-to-Curve 實現
    
    以太坊共識層使用 BLS12381_G2 曲線參數
    安全標籤:hts_eth2_example_v1
    """
    
    # 曲線參數
    p = bn128.curve_order  # 質數
    q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001  # G2 的階
    
    @classmethod
    def expand_message_xmd(cls, message: bytes, dst: bytes, len_bytes: int) -> bytes:
        """訊息擴展函數(expand_message_xmd)
        
        使用 hash_to_field 所需的安全擴展函數
        
        Args:
            message: 原始訊息
            dst: 域分離標籤(domain separation tag)
            len_bytes: 期望輸出位元組數
        """
        # SHA-256 或其他適合的雜湊函數
        Z_pad = b'\x00' * 64
        l_i_b_str = int_to_bytes(len_bytes, 2)
        msg_prime = Z_pad + int_to_bytes(len(message), 1) + message + l_i_b_str + b'\x00'
        
        # DST 處理
        ell = (len_bytes + 31) // 32
        msg_pieces = [b'']
        
        # 計算 b_0
        b_0 = hashlib.sha256(msg_prime + int_to_bytes(len(dst), 1) + dst + b'\x01').digest()
        msg_pieces.append(b_0)
        
        # 計算 b_i
        for i in range(1, ell + 1):
            b_i = hashlib.sha256(
                msg_pieces[i] + int_to_bytes(len(dst), 1) + dst + int_to_bytes(i, 1)
            ).digest()
            msg_pieces.append(b_i)
        
        result = b''.join(msg_pieces[1:])
        return result[:len_bytes]
    
    @classmethod
    def hash_to_field(cls, message: bytes, count: int) -> list:
        """Hash-to-Field:將訊息映射到有限域元素
        
        使用於 G₂ 的座標域
        """
        m = 12  # G₂ 的嵌入度
        L = 64  # 每個域元素需要 64 位元組
        
        DST = b'QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_R_'
        p_bytes = cls.expand_message_xmd(message, DST, count * m * L)
        
        u_values = []
        for i in range(count):
            u = []
            for j in range(m):
               엘 = bytes_to_int(p_bytes[(i*m + j)*L : (i*m + j + 1)*L])
                t_ij = 엘 mod cls.p
                u.append(t_ij)
            u_values.append(u)
        
        return u_values
    
    @classmethod
    def map_to_curve_swu(cls, u: list) -> Tuple[int, int]:
        """SWU 映射:將域元素映射到曲線點
        
        複雜的代數運算省略,實際應用建議使用成熟函式庫
        """
        # 簡化版本 - 實際使用 py_ecc 或 bls12_381 庫
        pass
    
    @classmethod
    def hash_to_point(cls, message: bytes) -> Tuple:
        """完整的 Hash-to-Point 流程
        
        以太坊共識層使用的標準方法
        """
        # 使用成熟函式庫
        from py_ecc.bls import hash_to_G2
        
        DST = b'QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_R_'
        return hash_to_G2(message, DST)

2.3 簽章生成與驗證

完整簽章流程實現

class BLSSignature:
    """BLS 簽章核心操作
    
    以太坊共識層使用 CP-ADP 變體:
    - 簽章位於 G₂
    - 公鑰位於 G₁
    - 使用 destandardized 配對
    """
    
    G1 = bn128.G1
    G2 = bn128.G2
    GT = bn128.GT
    n = bn128.curve_order
    
    @classmethod
    def sign(cls, private_key: int, message: bytes) -> Tuple:
        """產生 BLS 簽章
        
        簽章公式:σ = sk × H(m)
        其中 H(m) 是訊息雜湊到 G₂ 的結果
        
        Args:
            private_key: 私鑰整數
            message: 待簽章訊息(bytes)
            
        Returns:
            簽章點(位於 G₂)
        """
        # 將訊息雜湊到 G₂
        point_on_g2 = cls._hash_to_g2(message)
        
        # 在 G₂ 上執行標量乘法
        signature = bn128.G2.multiply(point_on_g2, private_key)
        
        return signature
    
    @classmethod
    def _hash_to_g2(cls, message: bytes) -> Tuple:
        """將訊息雜湊到 G₂ 群
        
        以太坊使用的標準方法
        """
        # 實現細節:使用 RFC 9380
        # 返回 (x1, y1, x2, y2) 四個座標分量
        from py_ecc.bls import hash_to_G2
        DST = b'QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_R_'
        return hash_to_G2(message, DST)
    
    @classmethod
    def verify(cls, public_key: Tuple, message: bytes, signature: Tuple) -> bool:
        """驗證 BLS 簽章
        
        驗證公式:e(σ, G) == e(H(m), P)
        
        其中:
        - σ 是簽章
        - G 是 G₁ 的生成元
        - H(m) 是訊息的 G₂ 哈希
        - P 是公鑰
        
        Args:
            public_key: 公鑰座標 (x, y)
            message: 原始訊息
            signature: 簽章
            
        Returns:
            True 表示驗證通過
        """
        # 將訊息雜湊到 G₂
        point_g2 = cls._hash_to_g2(message)
        
        # 配對運算左側:e(σ, G)
        pairing_left = bn128.pairing(signature, cls.G1)
        
        # 配對運算右側:e(H(m), P)
        pairing_right = bn128.pairing(point_g2, public_key)
        
        # 比較兩個配對結果
        return pairing_left == pairing_right
    
    @classmethod
    def aggregate_signatures(cls, signatures: list) -> Tuple:
        """聚合多個簽章
        
        聚合公式:σ_agg = Σ σᵢ = (Σ skᵢ) × H(m)
        
        這個聚合是非互動式的——各簽章者可獨立生成簽章,
        然後簡單地將其相加即可
        
        Args:
            signatures: 簽章列表
            
        Returns:
            聚合後的單一簽章
        """
        # G₂ 上的標量加法
        agg_sig = signatures[0]
        for sig in signatures[1:]:
            agg_sig = bn128.G2.add(agg_sig, sig)
        return agg_sig
    
    @classmethod
    def aggregate_public_keys(cls, public_keys: list) -> Tuple:
        """聚合多個公鑰
        
        聚合公式:P_agg = Σ Pᵢ = Σ (skᵢ × G)
        
        Args:
            public_keys: 公鑰列表
            
        Returns:
            聚合後的單一公鑰
        """
        agg_pk = public_keys[0]
        for pk in public_keys[1:]:
            agg_pk = bn128.G1.add(agg_pk, pk)
        return agg_pk
    
    @classmethod
    def fast_aggregate_verify(cls, public_keys: list, message: bytes, 
                              signature: Tuple) -> bool:
        """快速聚合驗證
        
        O(1) 複雜度驗證,與簽章數量無關
        
        驗證公式:e(σ_agg, G) == e(H(m), Σ Pᵢ)
        
        Args:
            public_keys: 公鑰列表
            message: 原始訊息(所有簽章者簽署相同訊息)
            signature: 聚合簽章
            
        Returns:
            True 表示驗證通過
        """
        # 聚合公鑰
        agg_pk = cls.aggregate_public_keys(public_keys)
        
        # 將訊息雜湊到 G₂
        point_g2 = cls._hash_to_g2(message)
        
        # 配對驗證
        pairing_left = bn128.pairing(signature, cls.G1)
        pairing_right = bn128.pairing(point_g2, agg_pk)
        
        return pairing_left == pairing_right

# 使用範例
bls = BLSSignature()

# 生成多個金鑰對
keypairs = [BLSKeyGenerator.keygen() for _ in range(3)]
private_keys = [sk for sk, _ in keypairs]
public_keys = [pk for _, pk in keypairs]

# 簽署相同訊息
message = b"Hello, Ethereum!"
signatures = [bls.sign(sk, message) for sk in private_keys]

# 聚合簽章
agg_sig = bls.aggregate_signatures(signatures)

# 快速驗證
result = bls.fast_aggregate_verify(public_keys, message, agg_sig)
print(f"聚合簽章驗證結果: {result}")

三、以太坊共識層 BLS 操作實務

3.1 Validator 公私鑰管理

以太坊驗證者的 BLS 金鑰管理涉及兩層金鑰:

提款金鑰(Withdrawal Keys)

驗證者金鑰(Validator Keys)

EIP-2334 派生路徑

purpose' = 12381   # BLS12-381 曲線標識
coin'    = 3600    # Ethereum 用途標識
account' = 0       # 帳戶索引
withdrawal' = 0    # 提款用途
commitment' = 0    # 驗證者用途

完整路徑:m/12381/3600/0'/0'/0

3.2 驗證者簽章操作

以太坊共識層的簽章操作可分為以下幾類:

Attestation 簽章

class AttestationSigning:
    """Attestation 簽章操作
    
    每個 slot,驗證者需要對區塊提議者的區塊頭進行簽章
    """
    
    DOMAIN_ATTESTATION = 0x01000000
    
    @classmethod
    def sign_attestation(cls, validator_sk: int, slot: int, 
                         beacon_block_root: bytes,
                         source_checkpoint: Checkpoint,
                         target_checkpoint: Checkpoint) -> bytes:
        """簽署 attestation
        
        簽章域包含:
        - slot:用於防止重放攻擊
        - source:當前 justified 檢查點
        - target:提議的檢查點
        """
        # 構造簽章資料
        signing_data = struct.pack(
            "<QQ32s32s32s",
            slot,
            source_checkpoint.epoch,
            source_checkpoint.root,
            target_checkpoint.epoch,
            target_checkpoint.root
        )
        
        # 計算簽章域
        domain = cls._compute_domain(
            cls.DOMAIN_ATTESTATION,
            beacon_block_root[:4]  # fork_version
        )
        
        # 簽章
        signing_root = cls._compute_signing_root(signing_data, domain)
        point_g2 = hash_to_G2(signing_root, DST)
        signature = G2.multiply(point_g2, validator_sk)
        
        return signature

區塊提議簽章

class BlockSigning:
    """區塊提議簽章操作
    
    驗證者被選為 slot 提議者時需要簽署區塊
    """
    
    DOMAIN_BEACON_BLOCK = 0x00000000
    
    @classmethod
    def sign_block(cls, validator_sk: int, slot: int,
                   beacon_block_root: bytes,
                   fork_version: bytes) -> bytes:
        """簽署區塊提議
        """
        signing_data = struct.pack(
            "<Q32s",
            slot,
            beacon_block_root
        )
        
        domain = cls._compute_domain(
            cls.DOMAIN_BEACON_BLOCK,
            fork_version
        )
        
        signing_root = cls._compute_signing_root(signing_data, domain)
        point_g2 = hash_to_G2(signing_root, DST)
        signature = G2.multiply(point_g2, validator_sk)
        
        return signature

3.3 批次驗證優化

以太坊共識層需要驗證來自數千個驗證者的簽章。批次驗證是關鍵優化:

批次驗證原理

class BatchVerification:
    """BLS 批次驗證優化
    
    利用簽章聚合的逆運算實現高效批次驗證
    """
    
    @classmethod
    def aggregate_verify_batch(cls, public_keys: list, 
                               messages: list,
                               signatures: list) -> bool:
        """批次驗證多個簽章
        
        標準方法:每個簽章獨立驗證
        時間複雜度:O(n)
        """
        for pk, msg, sig in zip(public_keys, messages, signatures):
            if not BLSSignature.verify(pk, msg, sig):
                return False
        return True
    
    @classmethod
    def aggregate_verify_optimized(cls, public_keys: list,
                                   messages: list,
                                   signatures: list) -> bool:
        """優化的批次驗證
        
        使用隨機線性組合(Lagrange 插值思想)
        時間複雜度:O(n) 配對 → O(1) 配對
        
        核心思想:
        若要驗證 n 個簽章
        選擇隨機係數 r₁, r₂, ..., rₙ
        驗證 Σ(rᵢ × σᵢ) 對 Σ(rᵢ × Pᵢ) 的配對
        
        這在代數上等價於驗證所有原始簽章
        但只需要 2 個配對運算
        """
        from random import randint
        
        n = len(public_keys)
        
        # 生成隨機係數
        random_coefficients = [randint(1, 2**32) for _ in range(n)]
        
        # 計算加權聚合簽章
        agg_sig = (0, 0, 0, 0)
        for i, sig in enumerate(signatures):
            weighted_sig = bn128.G2.multiply(sig, random_coefficients[i])
            agg_sig = bn128.G2.add(agg_sig, weighted_sig)
        
        # 計算加權聚合公鑰(需要對應的 G₁ 點)
        # 但這裡的複雜性在於訊息不同
        # 需要使用多配對驗證
        
        return cls._multi_pairing_verify(
            list(zip(public_keys, messages, signatures)),
            random_coefficients
        )
    
    @classmethod
    def _multi_pairing_verify(cls, items: list, coeffs: list) -> bool:
        """多配對驗證
        
        使用單一配對方程驗證多個簽章:
        Π e(σᵢ, G)^rᵢ = Π e(H(m)ᵢ, Pᵢ)^rᵢ
        
        等價於:
        e(Σ rᵢσᵢ, G) = e(Σ rᵢH(m)ᵢ, Σ rᵢPᵢ) 
        (需要所有訊息相同)
        
        對於不同訊息:
        e(Σ rᵢσᵢ, G) = Π e(rᵢH(m)ᵢ, Pᵢ)
        """
        # 左側:e(Σ rᵢσᵢ, G)
        left_agg = bn128.G2.point_at_infinity()
        for i, (_, _, sig) in enumerate(items):
            weighted = bn128.G2.multiply(sig, coeffs[i])
            left_agg = bn128.G2.add(left_agg, weighted)
        left_pairing = bn128.pairing(left_agg, bn128.G1)
        
        # 右側:Π e(rᵢH(m)ᵢ, Pᵢ)
        right_pairing = bn128.GT.one()
        for i, (pk, msg, _) in enumerate(items):
            h_m = hash_to_G2(msg, DST)
            weighted_h = bn128.G2.multiply(h_m, coeffs[i])
            pair = bn128.pairing(weighted_h, pk)
            right_pairing = bn128.GT.multiply(right_pairing, pair)
        
        return left_pairing == right_pairing

四、實際部署考量

4.1 安全最佳實踐

私鑰保護

class SecureBLSKeyStorage:
    """安全的 BLS 金鑰存儲
    
    實際部署中應考慮:
    - 使用 KMS (Key Management Service)
    - 硬體安全模組 (HSM)
    - MPC 分割金鑰
    """
    
    @classmethod
    def generate_and_encrypt(cls, password: str) -> dict:
        """生成並加密金鑰
        
        使用 Argon2id 導出金鑰
        AES-256-GCM 加密
        """
        from Crypto.Protocol.KDF import Argon2
        from Crypto.Cipher import AES
        
        # 生成私鑰
        sk = BLSKeyGenerator.generate_private_key()
        pk = BLSKeyGenerator.derive_public_key(sk)
        
        # Argon2id 導出金鑰
        salt = os.urandom(16)
        key = Argon2(password, salt, 2**18, 8, 4, 32, 2)  # 18MB 記憶體
        
        # AES-256-GCM 加密
        nonce = os.urandom(12)
        cipher = AES.new(key, AES.MODE_GCM, nonce)
        encrypted_sk = cipher.encrypt(sk.to_bytes(32, 'big'))
        auth_tag = cipher.digest()
        
        return {
            'salt': salt.hex(),
            'nonce': nonce.hex(),
            'ciphertext': encrypted_sk.hex(),
            'auth_tag': auth_tag.hex(),
            'public_key': pk
        }
    
    @classmethod
    def decrypt_and_sign(cls, encrypted_data: dict, password: str, 
                        message: bytes) -> bytes:
        """解密並簽章
        """
        from Crypto.Protocol.KDF import Argon2
        from Crypto.Cipher import AES
        
        # 重建金鑰
        salt = bytes.fromhex(encrypted_data['salt'])
        key = Argon2(password, salt, 2**18, 8, 4, 32, 2)
        
        # 解密
        nonce = bytes.fromhex(encrypted_data['nonce'])
        cipher = AES.new(key, AES.MODE_GCM, nonce)
        sk = int.from_bytes(
            cipher.decrypt(bytes.fromhex(encrypted_data['ciphertext'])),
            'big'
        )
        
        # 驗證認證標籤
        cipher.verify(bytes.fromhex(encrypted_data['auth_tag']))
        
        # 簽章
        return BLSSignature.sign(sk, message)

4.2 效能優化

簽章速度優化

class OptimizedBLSSigning:
    """優化的 BLS 簽章操作
    
    以太坊驗證者客戶端使用以下優化:
    - 預計算表
    - 批量操作
    - SIMD 指令
    """
    
    @classmethod
    def precompute_table(cls, base_point: Tuple) -> list:
        """預計算窗口表
        
        將標量乘法改為查表操作
        窗口大小 4 位元:需要 8 個預計算點
        """
        w = 4  # 窗口大小
        table_size = 2**w
        
        table = [base_point]
        for i in range(1, table_size):
            table.append(
                bn128.G1.add(table[-1], base_point)
            )
        
        return table
    
    @classmethod
    def multiply_with_precomputation(cls, point: Tuple, 
                                     scalar: int,
                                     table: list) -> Tuple:
        """使用預計算表的快速標量乘法
        
        複雜度:O(log n / w) 而非 O(n)
        """
        w = 4
        result = bn128.G1.point_at_infinity()
        
        for i in range(256 // w):
            nibble = (scalar >> (i * w)) & 0xF
            if nibble >= len(table):
                nibble = nibble - 16
            result = bn128.G1.add(result, table[nibble])
            result = bn128.G1.multiply(result, 2**w)
        
        return result

4.3 錯誤處理與驗證

class BLSSignatureValidation:
    """BLS 簽章驗證的錯誤處理"""
    
    @staticmethod
    def validate_public_key(pk: Tuple) -> bool:
        """驗證公鑰有效性
        
        檢查點是否在曲線上
        """
        x, y = pk
        
        # 檢查是否為無窮遠點
        if x == 0 and y == 0:
            return False
        
        # 檢查是否在 G₁ 群階內
        if not (1 <= x < bn128.curve_order and 1 <= y < bn128.curve_order):
            return False
        
        # 檢查是否在曲線上:y² = x³ + 3
        lhs = (y * y) % bn128.curve_order
        rhs = (x * x * x + 3) % bn128.curve_order
        
        return lhs == rhs
    
    @staticmethod
    def validate_signature(sig: Tuple) -> bool:
        """驗證簽章有效性
        
        檢查簽章點是否在 G₂ 上
        """
        # G₂ 點的驗證更複雜
        # 需要驗證兩個座標分量都在正確的擴域中
        pass
    
    @staticmethod
    def safe_verify(pk: Tuple, message: bytes, sig: Tuple) -> bool:
        """安全的驗證接口
        
        包含所有必要的驗證步驟
        """
        # 驗證公鑰
        if not BLSSignatureValidation.validate_public_key(pk):
            return False
        
        # 驗證簽章格式
        if not BLSSignatureValidation.validate_signature(sig):
            return False
        
        # 執行實際驗證
        try:
            return BLSSignature.verify(pk, message, sig)
        except Exception:
            return False

五、與以太坊共識層的整合

5.1 Beacon Chain 操作

以太坊 Beacon Chain 使用 BLS 簽章處理以下關鍵操作:

Epoch 處理中的簽章聚合

class BeaconChainBLSOperations:
    """Beacon Chain BLS 操作整合"""
    
    @classmethod
    def process_attestations(cls, attestations: list) -> Tuple:
        """處理 attestations 並聚合簽章
        
        這是以太坊共識層最關鍵的 BLS 操作之一
        """
        # 按(slot, committee_index)分組
        from collections import defaultdict
        
        grouped = defaultdict(list)
        for attestation in attestations:
            key = (attestation.slot, attestation.committee_index)
            grouped[key].append(attestation)
        
        aggregated = []
        for key, atts in grouped.items():
            # 聚合同組的簽章
            sigs = [att.signature for att in atts]
            agg_sig = BLSSignature.aggregate_signatures(sigs)
            
            # 聚合公鑰
            pks = [cls.get_validator_pubkey(att.validator_index) 
                   for att in atts]
            agg_pk = BLSSignature.aggregate_public_keys(pks)
            
            aggregated.append({
                'slot': key[0],
                'committee_index': key[1],
                'aggregated_signature': agg_sig,
                'aggregated_public_key': agg_pk,
                'aggregation_bits': cls._compute_aggregation_bits(atts)
            })
        
        return aggregated
    
    @classmethod
    def verify_aggregated_attestation(cls, agg_att: dict, 
                                       message: bytes) -> bool:
        """驗證聚合的 attestation
        
        使用快速聚合驗證
        """
        return BLSSignature.fast_aggregate_verify(
            [agg_att['aggregated_public_key']],
            message,
            agg_att['aggregated_signature']
        )

5.2 同步委員會處理

同步委員會需要處理大量簽章:

class SyncCommitteeSignature:
    """同步委員會簽章操作
    
    同步委員會每 256 個 epoch(約 27 小時)更換一次
    每個 slot 需要聚合約 512 個驗證者的簽章
    """
    
    @classmethod
    def aggregate_sync_committee_signatures(cls, signatures: list,
                                           pubkeys: list) -> Tuple:
        """聚合同步委員會簽章"""
        return BLSSignature.aggregate_signatures(signatures)
    
    @classmethod
    def verify_sync_committee_aggregate(cls, 
                                        aggregated_signature: Tuple,
                                        sync_committee_pubkeys: list,
                                        beacon_block_root: bytes,
                                        slot: int) -> bool:
        """驗證同步委員會聚合簽章"""
        # 構造簽章域
        domain = cls._compute_sync_committee_domain(slot)
        signing_root = cls._compute_signing_root(beacon_block_root, domain)
        
        return BLSSignature.fast_aggregate_verify(
            sync_committee_pubkeys,
            signing_root,
            aggregated_signature
        )

結論

BLS 簽章是以太坊 PoS 共識機制的核心密碼學基礎。其獨特的簽章聚合特性使得網路能夠在保持去中心化的同時實現高效的共識確認。理解 BLS 簽章的數學原理與工程實現對於開發以太坊共識層工具、構建驗證者基礎設施、以及參與以太坊安全研究都有重要價值。


免責聲明:本網站內容僅供教育與資訊目的,不構成任何投資建議或推薦。在進行任何加密貨幣相關操作前,請自行研究並諮詢專業人士意見。所有投資均有風險,請謹慎評估您的風險承受能力。

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

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

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