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.
| Property | Value |
|---|---|
| Address | 0x0800000000000000000000000000000000000002 |
| Input | message || group_public_key (32 bytes) || signature (64 bytes) |
| Output | 0x01 (valid) or 0x00 (invalid) |
| Gas Cost | 3,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).
| Property | Value |
|---|---|
| Address | 0x0800000000000000000000000000000000000003 |
| Input | message_hash (32 bytes) || public_key (64 bytes) || signature (64 bytes) |
| Output | 0x01 (valid) or 0x00 (invalid) |
| Gas Cost | 4,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.
| Property | Value |
|---|---|
| Address | 0x020000000000000000000000000000000000000B |
| Input | message || group_public_key || signature || threshold_params |
| Output | 0x01 (valid) or 0x00 (invalid) |
| Gas Cost | 25,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:
- Distributed Key Generation (DKG) -- Generates key shares for
nparties with thresholdt - Signing Rounds -- Coordinates multi-party signing via secure channels (Hanzo PubSub)
- 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
| Property | FROST | CGGMP21 | Ringtail |
|---|---|---|---|
| Curve/Primitive | Schnorr (Ed25519/secp256k1) | ECDSA (secp256k1) | Ring-LWE |
| Quantum Resistant | No | No | Yes |
| Signature Size | 64 bytes | 64 bytes | ~2,500 bytes |
| Gas Cost | 3,500 | 4,000 | 25,000 |
| EVM Compatible | Schnorr verify | ecrecover compatible | Precompile only |
| Rounds (signing) | 2 | 4-6 | 3 |
| Key Resharing | Yes | Yes | Yes |
Is this guide helpful?