Files
zeekayandHanzo Dev 9ababce758 A precompile's config key names the precompile
Forty-five of the fifty-six suite modules keyed off <name>Config and eleven did
not, in three other spellings: Verify, Threshold, Encapsulate. The LP-4200
unified PQCrypto block carried four of those conventions across its eight
addresses — two KEMs named differently (mlkemConfig beside hqcEncapsulate) and
two threshold schemes named differently (pulsarVerify beside coronaThreshold) —
so the block that exists to be one thing did not read as one thing.

The deviations also named an OPERATION where a precompile belongs. HQC
decapsulates as well as encapsulates and the Verify precompiles do more than
verify, so hqcEncapsulate was the name of one entry point standing in for the
whole module. A config key selects a precompile; it is not a method selector.

All fifty-six are <name>Config now. There is no compatibility shim: an
upgrade.json naming an old key is naming something that does not exist, which
luxd already refuses loudly, and every chain config in the estate moves with this.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 19:27:25 -07:00
..

CGGMP21 Threshold Signature Precompile

Overview

The CGGMP21 (Canetti-Gennaro-Goldfeder-Makriyannis-Peled 2021) precompile enables threshold ECDSA signature verification. CGGMP21 is the state-of-the-art threshold signature protocol with identifiable aborts and efficient key refresh.

Address: 0x020000000000000000000000000000000000000D

Features

  • Threshold ECDSA: Any t out of n parties can sign
  • Identifiable Aborts: Malicious parties can be detected
  • Key Refresh: Update shares without changing public key
  • Standard ECDSA: Compatible with Ethereum, Bitcoin, etc.
  • MPC Custody: Enterprise-grade multi-party custody

Algorithm

CGGMP21 is a threshold signature scheme where:

  • n total parties hold shares of an ECDSA private key
  • Any t parties can collaborate to produce a valid signature
  • The signature is standard ECDSA (indistinguishable from single-party)
  • Malicious parties causing failures can be identified

Key Properties

  • Identifiable Aborts: Unlike GG20, can identify malicious parties
  • Efficient Refresh: Proactive security without downtime
  • Non-Interactive DKG: Efficient distributed key generation
  • Presignature Support: Precompute signatures for faster online phase

Specifications

Input Format

Total size: 170 bytes (minimum)

Offset Size Field Description
0-3 4 bytes threshold Minimum signers required (t)
4-7 4 bytes totalSigners Total number of parties (n)
8-72 65 bytes publicKey Aggregated ECDSA public key (uncompressed)
73-104 32 bytes messageHash Keccak256 hash of message
105-169 65 bytes signature ECDSA signature (r || s || v)

Output Format

32 bytes: Boolean result as uint256

  • 0x0000...0001 = Valid signature
  • 0x0000...0000 = Invalid signature

Gas Costs

Operation Base Gas Per-Signer Gas
CGGMP21 Verify 75,000 10,000

Examples:

  • 2-of-3 threshold: 75,000 + (3 × 10,000) = 105,000 gas
  • 3-of-5 threshold: 75,000 + (5 × 10,000) = 125,000 gas
  • 5-of-7 threshold: 75,000 + (7 × 10,000) = 145,000 gas
  • 10-of-15 threshold: 75,000 + (15 × 10,000) = 225,000 gas

Usage Examples

Solidity - Threshold Wallet

import "./ICGGMP21.sol";

contract MultiSigWallet is CGGMP21Verifier {
    bytes public thresholdPublicKey;
    uint32 public threshold;
    uint32 public totalSigners;

    function executeWithThreshold(
        address to,
        uint256 value,
        bytes calldata data,
        bytes calldata signature
    ) external {
        bytes32 txHash = keccak256(abi.encodePacked(to, value, data, nonce));

        verifyCGGMP21Signature(
            threshold,
            totalSigners,
            thresholdPublicKey,
            txHash,
            signature
        );

        // Execute transaction
        (bool success, ) = to.call{value: value}(data);
        require(success, "Execution failed");
    }
}

TypeScript (ethers.js)

const CGGMP21 = new ethers.Contract(
    '0x020000000000000000000000000000000000000D',
    [
        'function verify(uint32,uint32,bytes,bytes32,bytes) view returns(bool)'
    ],
    provider
);

// Verify 3-of-5 threshold ECDSA signature
const isValid = await CGGMP21.verify(
    3,              // threshold
    5,              // totalSigners
    publicKey,      // 65 bytes uncompressed
    messageHash,    // 32 bytes
    signature       // 65 bytes ECDSA
);

Go - MPC Integration

import (
    "github.com/luxfi/mpc/pkg/protocol/cggmp21"
)

// Initialize CGGMP21 protocol
protocol := cggmp21.NewProtocol()

// Distributed key generation (3-of-5)
keygenParty, err := protocol.KeyGen("party1", partyIDs, 3)
config := keygenParty.Result()

// Threshold signing
signParty, err := protocol.Sign(config, signers, messageHash)
signature := signParty.Result()

// Verify on-chain via precompile

Use Cases

1. Multi-Party Custody

contract InstitutionalCustody is CGGMP21Verifier {
    // 5-of-7 threshold for institutional custody
    uint32 constant THRESHOLD = 5;
    uint32 constant TOTAL_SIGNERS = 7;

    function transferAssets(
        address token,
        address to,
        uint256 amount,
        bytes calldata thresholdSig
    ) external {
        bytes32 txHash = keccak256(abi.encodePacked(token, to, amount));

        verifyCGGMP21Signature(
            THRESHOLD,
            TOTAL_SIGNERS,
            custodyPublicKey,
            txHash,
            thresholdSig
        );

        IERC20(token).transfer(to, amount);
    }
}

2. DAO Treasury Management

contract DAOTreasury is CGGMP21Verifier {
    // 7-of-10 DAO council
    function executeDAODecision(
        bytes32 proposalId,
        bytes calldata executionData,
        bytes calldata councilSignature
    ) external {
        verifyCGGMP21Signature(
            DAO_THRESHOLD,
            DAO_COUNCIL_SIZE,
            daoPublicKey,
            proposalId,
            councilSignature
        );

        // Execute DAO decision
    }
}

3. Cross-Chain Bridge

contract ThresholdBridge is CGGMP21Verifier {
    // Validators sign cross-chain messages
    function relayMessage(
        uint256 sourceChain,
        bytes calldata message,
        bytes calldata validatorSig
    ) external {
        bytes32 messageHash = keccak256(abi.encodePacked(
            sourceChain,
            block.chainid,
            message
        ));

        verifyCGGMP21Signature(
            VALIDATOR_THRESHOLD,
            TOTAL_VALIDATORS,
            validatorPublicKey,
            messageHash,
            validatorSig
        );

        // Process cross-chain message
    }
}

Security Considerations

Threshold Selection

  • 2-of-3: Small teams, personal wallets
  • 3-of-5: Standard multi-sig, small DAOs
  • 5-of-7: Medium security, trading firms
  • 7-of-10 or higher: High security, institutional custody

Key Management

  • Key Refresh: Periodically refresh shares for proactive security
  • Backup Shares: Securely backup threshold shares
  • Identifiable Aborts: Monitor and remove malicious parties
  • Share Distribution: Never store all shares in one location

Message Hashing

Always hash messages with domain separation:

bytes32 domainHash = keccak256(abi.encodePacked(
    address(this),
    block.chainid,
    "CGGMP21-v1"
));

bytes32 messageHash = keccak256(abi.encodePacked(
    domainHash,
    nonce,
    data
));

Performance

Benchmarks on Apple M1 Max:

Configuration Gas Cost Verify Time Memory
2-of-3 105,000 ~65 μs 12 KB
3-of-5 125,000 ~80 μs 14 KB
5-of-7 145,000 ~95 μs 16 KB
10-of-15 225,000 ~140 μs 22 KB

Comparison with Other Schemes

Algorithm Type Signature Size Gas Cost Identifiable Aborts
CGGMP21 (this) ECDSA 65 bytes 75k-225k ✅
FROST Schnorr 64 bytes 50k-125k ❌
GG20 ECDSA 65 bytes 75k-225k ❌
BLS (Warp) BLS12-381 96 bytes 120k ✅

Integration with Lux MPC

This precompile integrates with /Users/z/work/lux/mpc/pkg/protocol/cggmp21:

import "github.com/luxfi/mpc/pkg/protocol/cggmp21"

// The MPC library provides:
// - protocol.KeyGen() - Distributed key generation
// - protocol.Sign() - Threshold signing
// - protocol.Refresh() - Share refreshing
// - protocol.PreSign() - Presignature generation

Standards Compliance

  • CGGMP21 Paper: ePrint 2021/060
  • ECDSA: secp256k1 curve (Bitcoin/Ethereum)
  • EIP-191: Signed data standard

References