PQ Precompiles

Threshold Signatures

Precompiles for verifying threshold signatures from FROST, CGGMP21, and Ringtail protocols on the Lux EVM.

Overview

Threshold signature schemes allow a group of n parties to jointly produce a signature such that any t of them (the threshold) can sign, but fewer than t cannot. The Lux EVM provides precompiles for verifying three threshold signature protocols:

  • FROST -- Threshold Schnorr signatures (Ed25519 and secp256k1)
  • CGGMP21 -- Threshold ECDSA on secp256k1
  • Ringtail -- Post-quantum threshold signatures based on Ring-LWE

These precompiles verify the final aggregated signature. The multi-party key generation and signing ceremonies happen off-chain (e.g., via Lux MPC).

FROST Verify

Verifies threshold Schnorr signatures produced by the FROST (Flexible Round-Optimized Schnorr Threshold) protocol.

PropertyValue
Address0x0800000000000000000000000000000000000002
Inputmessage || group_public_key (32 bytes) || signature (64 bytes)
Output0x01 (valid) or 0x00 (invalid)
Gas Cost3,500

FROST produces standard Schnorr signatures that are indistinguishable from single-signer Schnorr signatures. The verifier does not need to know the threshold parameters -- it verifies against the group public key exactly like a normal Schnorr verification.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract FROSTVerifier {
    address constant FROST = 0x0800000000000000000000000000000000000002;

    /// @notice Verify a FROST threshold Schnorr signature
    /// @param message The signed message
    /// @param groupPublicKey The group public key (aggregated from key shares)
    /// @param signature The aggregated FROST signature (R || s, 64 bytes)
    function verify(
        bytes memory message,
        bytes32 groupPublicKey,
        bytes memory signature
    ) external view returns (bool) {
        (bool success, bytes memory result) = FROST.staticcall(
            abi.encodePacked(message, groupPublicKey, signature)
        );
        return success && result.length > 0 && uint8(result[0]) == 1;
    }
}

FROST Use Cases

  • Multi-sig wallets -- 2-of-3 or 3-of-5 custody without on-chain multi-sig overhead
  • DAO treasury -- Threshold control of funds with a single on-chain signature
  • Cross-chain bridges -- Validator committees sign attestations using FROST, verified on-chain

CGGMP21 Verify

Verifies threshold ECDSA signatures produced by the CGGMP21 protocol (Canetti-Gennaro-Goldfeder-Makriyannis-Peled, 2021).

PropertyValue
Address0x0800000000000000000000000000000000000003
Inputmessage_hash (32 bytes) || public_key (64 bytes) || signature (64 bytes)
Output0x01 (valid) or 0x00 (invalid)
Gas Cost4,000

CGGMP21 produces standard ECDSA signatures on secp256k1, making them compatible with existing Ethereum infrastructure. The output signature is indistinguishable from a normal ecrecover-compatible signature.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract CGGMP21Verifier {
    address constant CGGMP21 = 0x0800000000000000000000000000000000000003;

    /// @notice Verify a CGGMP21 threshold ECDSA signature
    /// @param messageHash The keccak256 hash of the signed message
    /// @param publicKey The group public key (uncompressed, 64 bytes: x || y)
    /// @param signature The aggregated ECDSA signature (r || s, 64 bytes)
    function verify(
        bytes32 messageHash,
        bytes memory publicKey,
        bytes memory signature
    ) external view returns (bool) {
        (bool success, bytes memory result) = CGGMP21.staticcall(
            abi.encodePacked(messageHash, publicKey, signature)
        );
        return success && result.length > 0 && uint8(result[0]) == 1;
    }
}

Since CGGMP21 produces standard secp256k1 ECDSA signatures, you can also verify them using the built-in ecrecover precompile. The CGGMP21 precompile is provided for explicit verification against the full group public key (not just the derived address).

CGGMP21 Use Cases

  • Institutional custody -- MPC wallets where multiple parties hold key shares (e.g., customer + exchange + backup)
  • Settlement signing -- Lux MPC uses CGGMP21 for threshold-signed settlement transactions with HSM co-signing
  • Backward compatibility -- Produce Ethereum-compatible signatures from threshold key shares

Ringtail Threshold Verify

Verifies post-quantum threshold signatures based on Ring Learning With Errors (Ring-LWE). Ringtail combines the quantum resistance of lattice-based cryptography with the distributed trust of threshold signatures.

PropertyValue
Address0x020000000000000000000000000000000000000B
Inputmessage || group_public_key || signature || threshold_params
Output0x01 (valid) or 0x00 (invalid)
Gas Cost25,000

Unlike FROST and CGGMP21 where the aggregated signature is indistinguishable from a single-signer signature, Ringtail signatures include threshold metadata that the verifier uses. The threshold_params field encodes t (threshold) and n (total parties).

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract RingtailVerifier {
    address constant RINGTAIL = 0x020000000000000000000000000000000000000B;

    /// @notice Verify a Ringtail post-quantum threshold signature
    /// @param message The signed message
    /// @param groupPublicKey The group public key
    /// @param signature The aggregated Ringtail signature
    /// @param thresholdParams Encoded threshold parameters (t, n)
    function verify(
        bytes memory message,
        bytes memory groupPublicKey,
        bytes memory signature,
        bytes memory thresholdParams
    ) external view returns (bool) {
        (bool success, bytes memory result) = RINGTAIL.staticcall(
            abi.encodePacked(message, groupPublicKey, signature, thresholdParams)
        );
        return success && result.length > 0 && uint8(result[0]) == 1;
    }
}

Ringtail Use Cases

  • Quantum-safe custody -- Post-quantum multi-party wallets for long-term asset protection
  • PQ bridge validators -- Bridge committee signatures that remain secure against quantum computers
  • Hybrid signing -- Use Ringtail alongside FROST/CGGMP21 for defense-in-depth

Use with Lux MPC

Lux MPC provides the off-chain infrastructure for threshold key generation and signing. The MPC service handles:

  1. Distributed Key Generation (DKG) -- Generates key shares for n parties with threshold t
  2. Signing Rounds -- Coordinates multi-party signing via secure channels (Hanzo PubSub)
  3. HSM Co-signing -- Optional hardware security module co-signing for settlement intents

The on-chain precompiles complete the picture by enabling smart contracts to verify the resulting threshold signatures.

Off-chain (Lux MPC)              On-chain (Lux EVM)
┌──────────────────┐             ┌──────────────────┐
│  Key Generation  │             │                  │
│  (DKG)           │             │  Smart Contract  │
│       ↓          │             │       ↓          │
│  Signing Round   │──signature──│  FROST / CGGMP21 │
│  (t-of-n)        │             │  / Ringtail      │
│       ↓          │             │  Precompile      │
│  HSM Co-sign     │             │       ↓          │
│  (optional)      │             │  Valid / Invalid │
└──────────────────┘             └──────────────────┘

Comparison

PropertyFROSTCGGMP21Ringtail
Curve/PrimitiveSchnorr (Ed25519/secp256k1)ECDSA (secp256k1)Ring-LWE
Quantum ResistantNoNoYes
Signature Size64 bytes64 bytes~2,500 bytes
Gas Cost3,5004,00025,000
EVM CompatibleSchnorr verifyecrecover compatiblePrecompile only
Rounds (signing)24-63
Key ResharingYesYesYes

Is this guide helpful?