chore: remove .DS_Store, orphaned .sol files, rewrite README

- Remove .DS_Store, add to .gitignore
- Remove AIMining.sol, IAllowList.sol, TeleportBridge.sol (orphaned,
  not referenced from any Go code)
- Rewrite README to match actual packages, addresses, and gas costs
This commit is contained in:
2026-03-02 19:54:17 +00:00
parent cd3d40efda
commit 912e0a0352
6 changed files with 87 additions and 1241 deletions
Vendored
BIN
View File
Binary file not shown.
+1
View File
@@ -1,3 +1,4 @@
.DS_Store
AGENTS.md
CLAUDE.md
GEMINI.md
-333
View File
@@ -1,333 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/**
* @title IAIMining
* @notice Interface for the AI Mining precompile at address 0x0300
* @dev Enables EVM contracts to interact with the Hanzo AI Mining Protocol
*
* This precompile provides:
* - Mining balance queries for ML-DSA addresses
* - ML-DSA (FIPS 204) signature verification
* - Teleport transfer claiming from Hanzo L1
* - Pending teleport queries
*
* References:
* - LP-2000: AI Mining Standard
* - HIP-006: Hanzo AI Mining Protocol
* - ZIP-005: Zoo AI Mining Integration
* - FIPS 204: Module-Lattice Digital Signature Algorithm (ML-DSA)
*/
interface IAIMining {
// ============ Events ============
/// @notice Emitted when mining rewards are claimed via Teleport
event TeleportClaimed(
bytes32 indexed teleportId,
address indexed recipient,
uint256 amount
);
/// @notice Emitted when ML-DSA signature verification is performed
event MLDSAVerified(
bytes32 indexed publicKeyHash,
bytes32 indexed messageHash,
bool success
);
// ============ View Functions ============
/**
* @notice Get the mining balance for an address
* @param miner The address to query (derived from ML-DSA public key)
* @return The mining balance in AI token atomic units
*/
function miningBalance(address miner) external view returns (uint256);
/**
* @notice Verify an ML-DSA signature (FIPS 204)
* @param publicKey The ML-DSA public key (1312-4627 bytes depending on security level)
* @param message The message that was signed
* @param signature The ML-DSA signature (2420-4627 bytes depending on security level)
* @return True if signature is valid, false otherwise
*
* @dev Supported security levels:
* - Level 2 (ML-DSA-44): 1312 byte pk, 2420 byte sig
* - Level 3 (ML-DSA-65): 1952 byte pk, 3309 byte sig
* - Level 5 (ML-DSA-87): 2592 byte pk, 4627 byte sig
*/
function verifyMLDSA(
bytes calldata publicKey,
bytes calldata message,
bytes calldata signature
) external view returns (bool);
/**
* @notice Get the security level of an ML-DSA public key
* @param publicKey The ML-DSA public key
* @return level The security level (2, 3, or 5)
*/
function getSecurityLevel(bytes calldata publicKey) external pure returns (uint8 level);
/**
* @notice Derive an address from an ML-DSA public key
* @param publicKey The ML-DSA public key
* @return The derived 20-byte address (BLAKE3 hash truncated)
*/
function deriveAddress(bytes calldata publicKey) external pure returns (address);
/**
* @notice Get pending teleport transfers for a recipient
* @param recipient The recipient address
* @return Array of pending teleport IDs
*/
function pendingTeleports(address recipient) external view returns (bytes32[] memory);
/**
* @notice Get details of a specific teleport transfer
* @param teleportId The unique teleport identifier
* @return sender The sender's ML-DSA public key hash
* @return recipient The recipient address
* @return amount The transfer amount
* @return sourceChain The source chain ID (always Hanzo L1)
* @return status The transfer status (0=pending, 1=claimed, 2=expired)
*/
function getTeleportDetails(bytes32 teleportId)
external
view
returns (
bytes32 sender,
address recipient,
uint256 amount,
uint256 sourceChain,
uint8 status
);
// ============ State-Changing Functions ============
/**
* @notice Claim teleported AI rewards from Hanzo L1
* @param teleportId The unique teleport transfer identifier
* @return The amount of AI tokens claimed
*
* @dev Requirements:
* - Teleport must exist and be in pending status
* - Caller must be the designated recipient
* - Teleport must not be expired (24 hour window)
*/
function claimTeleport(bytes32 teleportId) external returns (uint256);
/**
* @notice Batch claim multiple teleport transfers
* @param teleportIds Array of teleport IDs to claim
* @return totalAmount Total AI tokens claimed
*/
function batchClaimTeleports(bytes32[] calldata teleportIds) external returns (uint256 totalAmount);
}
/**
* @title AIMiningPrecompile
* @notice Implementation contract that wraps calls to the precompile at 0x0300
* @dev This contract provides a convenient wrapper for calling the precompile
* with proper error handling and gas estimation
*/
contract AIMiningPrecompile {
/// @notice The precompile address for AI Mining operations
address public constant PRECOMPILE_ADDRESS = address(0x0300);
/// @notice Chain IDs supported by Teleport
uint256 public constant HANZO_EVM_CHAIN_ID = 36963;
uint256 public constant ZOO_EVM_CHAIN_ID = 200200;
uint256 public constant LUX_CCHAIN_CHAIN_ID = 96369;
/// @notice ML-DSA security levels
uint8 public constant SECURITY_LEVEL_2 = 2;
uint8 public constant SECURITY_LEVEL_3 = 3;
uint8 public constant SECURITY_LEVEL_5 = 5;
/// @notice ML-DSA public key sizes per security level
uint256 public constant PK_SIZE_LEVEL_2 = 1312;
uint256 public constant PK_SIZE_LEVEL_3 = 1952;
uint256 public constant PK_SIZE_LEVEL_5 = 2592;
/// @notice ML-DSA signature sizes per security level
uint256 public constant SIG_SIZE_LEVEL_2 = 2420;
uint256 public constant SIG_SIZE_LEVEL_3 = 3309;
uint256 public constant SIG_SIZE_LEVEL_5 = 4627;
// ============ Errors ============
error PrecompileCallFailed();
error InvalidPublicKeySize();
error InvalidSignatureSize();
error TeleportNotFound();
error TeleportAlreadyClaimed();
error TeleportExpired();
error NotTeleportRecipient();
// ============ Events ============
event TeleportClaimedViaWrapper(
bytes32 indexed teleportId,
address indexed claimer,
uint256 amount
);
// ============ External Functions ============
/**
* @notice Get mining balance for an address
* @param miner The miner address to query
* @return balance The mining balance
*/
function getMiningBalance(address miner) external view returns (uint256 balance) {
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
abi.encodeWithSelector(IAIMining.miningBalance.selector, miner)
);
if (!success) revert PrecompileCallFailed();
return abi.decode(result, (uint256));
}
/**
* @notice Verify an ML-DSA signature
* @param publicKey The signer's public key
* @param message The signed message
* @param signature The ML-DSA signature
* @return isValid True if signature is valid
*/
function verifySignature(
bytes calldata publicKey,
bytes calldata message,
bytes calldata signature
) external view returns (bool isValid) {
// Validate public key size
if (publicKey.length != PK_SIZE_LEVEL_2 &&
publicKey.length != PK_SIZE_LEVEL_3 &&
publicKey.length != PK_SIZE_LEVEL_5) {
revert InvalidPublicKeySize();
}
// Validate signature size matches public key level
uint8 level = _getSecurityLevelFromPKSize(publicKey.length);
uint256 expectedSigSize = _getSignatureSizeForLevel(level);
if (signature.length != expectedSigSize) {
revert InvalidSignatureSize();
}
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
abi.encodeWithSelector(
IAIMining.verifyMLDSA.selector,
publicKey,
message,
signature
)
);
if (!success) revert PrecompileCallFailed();
return abi.decode(result, (bool));
}
/**
* @notice Claim a teleport transfer
* @param teleportId The teleport to claim
* @return amount The claimed amount
*/
function claim(bytes32 teleportId) external returns (uint256 amount) {
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.call(
abi.encodeWithSelector(IAIMining.claimTeleport.selector, teleportId)
);
if (!success) revert PrecompileCallFailed();
amount = abi.decode(result, (uint256));
emit TeleportClaimedViaWrapper(teleportId, msg.sender, amount);
return amount;
}
/**
* @notice Get all pending teleports for caller
* @return teleportIds Array of pending teleport IDs
*/
function getMyPendingTeleports() external view returns (bytes32[] memory teleportIds) {
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
abi.encodeWithSelector(IAIMining.pendingTeleports.selector, msg.sender)
);
if (!success) revert PrecompileCallFailed();
return abi.decode(result, (bytes32[]));
}
/**
* @notice Derive address from ML-DSA public key
* @param publicKey The public key bytes
* @return addr The derived address
*/
function addressFromPublicKey(bytes calldata publicKey) external view returns (address addr) {
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
abi.encodeWithSelector(IAIMining.deriveAddress.selector, publicKey)
);
if (!success) revert PrecompileCallFailed();
return abi.decode(result, (address));
}
// ============ Internal Functions ============
function _getSecurityLevelFromPKSize(uint256 size) internal pure returns (uint8) {
if (size == PK_SIZE_LEVEL_2) return SECURITY_LEVEL_2;
if (size == PK_SIZE_LEVEL_3) return SECURITY_LEVEL_3;
if (size == PK_SIZE_LEVEL_5) return SECURITY_LEVEL_5;
revert InvalidPublicKeySize();
}
function _getSignatureSizeForLevel(uint8 level) internal pure returns (uint256) {
if (level == SECURITY_LEVEL_2) return SIG_SIZE_LEVEL_2;
if (level == SECURITY_LEVEL_3) return SIG_SIZE_LEVEL_3;
if (level == SECURITY_LEVEL_5) return SIG_SIZE_LEVEL_5;
revert InvalidPublicKeySize();
}
}
/**
* @title AIMiningHelper
* @notice Helper library for AI Mining integration
*/
library AIMiningHelper {
address constant PRECOMPILE = address(0x0300);
/**
* @notice Quick check if an address has mining balance
* @param miner The address to check
* @return hasFunds True if balance > 0
*/
function hasMiningFunds(address miner) internal view returns (bool hasFunds) {
(bool success, bytes memory result) = PRECOMPILE.staticcall(
abi.encodeWithSelector(IAIMining.miningBalance.selector, miner)
);
if (!success) return false;
return abi.decode(result, (uint256)) > 0;
}
/**
* @notice Verify ML-DSA signature (returns false on failure instead of reverting)
*/
function safeVerifyMLDSA(
bytes memory publicKey,
bytes memory message,
bytes memory signature
) internal view returns (bool) {
(bool success, bytes memory result) = PRECOMPILE.staticcall(
abi.encodeWithSelector(
IAIMining.verifyMLDSA.selector,
publicKey,
message,
signature
)
);
if (!success) return false;
return abi.decode(result, (bool));
}
}
-141
View File
@@ -1,141 +0,0 @@
// SPDX-License-Identifier: MIT
// Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
pragma solidity ^0.8.0;
/**
* @title IAllowList
* @dev Base interface for allow-list managed precompiles
*
* The AllowList is a permission system used across multiple Lux EVM precompiles.
* It defines four roles with different permission levels:
*
* Roles:
* - None (0): No permissions
* - Enabled (1): Can use the precompile functionality
* - Admin (2): Can modify roles for any address
* - Manager (3): Can modify roles for non-admin addresses (added in Durango)
*
* Role Hierarchy:
* - Admin > Manager > Enabled > None
* - Admins can set any role for any address
* - Managers can set roles for Enabled and None addresses only
*
* Events:
* - RoleSet: Emitted when a role is changed
*/
interface IAllowList {
/**
* @notice Emitted when a role is set
* @param role The new role being set
* @param account The address receiving the role
* @param sender The address setting the role
* @param oldRole The previous role of the account
*/
event RoleSet(uint256 indexed role, address indexed account, address indexed sender, uint256 oldRole);
/**
* @notice Read the allow list role for an address
* @param addr The address to check
* @return role The role of the address (0=None, 1=Enabled, 2=Admin, 3=Manager)
*/
function readAllowList(address addr) external view returns (uint256 role);
/**
* @notice Set an address as Admin (role 2)
* @dev Only callable by Admin
* @param addr The address to set as Admin
*/
function setAdmin(address addr) external;
/**
* @notice Set an address as Enabled (role 1)
* @dev Callable by Admin or Manager
* @param addr The address to enable
*/
function setEnabled(address addr) external;
/**
* @notice Set an address as Manager (role 3)
* @dev Only callable by Admin. Added in Durango upgrade.
* @param addr The address to set as Manager
*/
function setManager(address addr) external;
/**
* @notice Remove all permissions from an address (role 0)
* @dev Callable by Admin or Manager (for non-admin addresses)
* @param addr The address to remove permissions from
*/
function setNone(address addr) external;
}
/**
* @title AllowListLib
* @dev Library for working with AllowList precompiles
*/
library AllowListLib {
/// @dev Role constants
uint256 constant ROLE_NONE = 0;
uint256 constant ROLE_ENABLED = 1;
uint256 constant ROLE_ADMIN = 2;
uint256 constant ROLE_MANAGER = 3;
/// @dev Gas costs
uint256 constant READ_ALLOWLIST_GAS = 2600;
uint256 constant MODIFY_ALLOWLIST_GAS = 20000;
error NotAdmin();
error NotEnabled();
error NotManager();
/**
* @notice Check if an address has at least Enabled role
* @param allowList The allow list precompile address
* @param addr The address to check
* @return True if enabled, admin, or manager
*/
function isEnabled(address allowList, address addr) internal view returns (bool) {
uint256 role = IAllowList(allowList).readAllowList(addr);
return role >= ROLE_ENABLED;
}
/**
* @notice Check if an address is Admin
* @param allowList The allow list precompile address
* @param addr The address to check
* @return True if admin
*/
function isAdmin(address allowList, address addr) internal view returns (bool) {
return IAllowList(allowList).readAllowList(addr) == ROLE_ADMIN;
}
/**
* @notice Check if an address is Manager
* @param allowList The allow list precompile address
* @param addr The address to check
* @return True if manager
*/
function isManager(address allowList, address addr) internal view returns (bool) {
return IAllowList(allowList).readAllowList(addr) == ROLE_MANAGER;
}
/**
* @notice Require caller to be enabled
* @param allowList The allow list precompile address
*/
function requireEnabled(address allowList) internal view {
if (!isEnabled(allowList, msg.sender)) {
revert NotEnabled();
}
}
/**
* @notice Require caller to be admin
* @param allowList The allow list precompile address
*/
function requireAdmin(address allowList) internal view {
if (!isAdmin(allowList, msg.sender)) {
revert NotAdmin();
}
}
}
+86 -484
View File
@@ -1,508 +1,110 @@
# Lux Precompiled Contracts
This directory contains all precompiled contracts (precompiles) for the Lux blockchain ecosystem. Precompiles are special smart contracts implemented natively in the node software for performance-critical operations that would be too expensive or slow to implement in Solidity.
Native EVM precompiles for the Lux blockchain. Each precompile is a Go package that implements `contract.StatefulPrecompiledContract` and registers via `modules.RegisterModule()` in its `init()`.
## Overview
Geth provides `NewPrecompileAdapter()` to wrap these into geth-compatible precompiles. L1 chains select which precompiles to enable via `PrecompileOverrider`.
Precompiles are located at deterministic addresses starting from `0x0200000000000000000000000000000000000000`. They provide optimized implementations for cryptographic operations, cross-chain messaging, and chain configuration.
## Precompiles
## Precompile Addresses
### Post-Quantum Cryptography (baseline — all Lux chains)
| Address | Name | Description | LP |
|---------|------|-------------|-----|
| `0x0200000000000000000000000000000000000001` | **DeployerAllowList** | Access control for contract deployment | LP-315 |
| `0x0200000000000000000000000000000000000002` | **TxAllowList** | Access control for transaction execution | LP-316 |
| `0x0200000000000000000000000000000000000003` | **FeeManager** | Dynamic fee configuration and management | LP-314 |
| `0x0200000000000000000000000000000000000004` | **NativeMinter** | Mint and burn native LUX tokens | LP-317 |
| `0x0200000000000000000000000000000000000005` | **RewardManager** | Validator reward distribution | LP-318 |
| `0x0200000000000000000000000000000000000006` | **ML-DSA** | Post-quantum signature verification (FIPS 204) | LP-311 |
| `0x0200000000000000000000000000000000000007` | **SLH-DSA** | Hash-based signature verification (FIPS 205) | LP-312 |
| `0x0200000000000000000000000000000000000008` | **Warp** | Cross-chain messaging and attestation | LP-313 |
| `0x0200000000000000000000000000000000000009` | **PQCrypto** | General post-quantum cryptography operations | LP-310 |
| `0x020000000000000000000000000000000000000A` | **Quasar** | Advanced consensus operations | LP-99 |
| `0x020000000000000000000000000000000000000B` | **Corona** | Lattice-based threshold signatures (LWE) | LP-320 |
| `0x020000000000000000000000000000000000000C` | **FROST** | Schnorr/EdDSA threshold signatures | LP-321 |
| `0x020000000000000000000000000000000000000D` | **CGGMP21** | ECDSA threshold signatures with aborts | LP-322 |
| `0x020000000000000000000000000000000000000E` | **Bridge** | Cross-chain bridge verification | LP-323 (Reserved) |
| Package | Address | Description | Gas |
|---------|---------|-------------|-----|
| `mldsa` | `0x0200...0006` | ML-DSA-65 signature verify (FIPS 204) | 100k + 10/byte |
| `slhdsa` | `0x0600...0001` | SLH-DSA signature verify (FIPS 205) | 15k–250k by mode |
| `pqcrypto` | `0x9003` | ML-KEM key encapsulation + hybrid PQ ops | variable |
| `mlkem` | `0x0200...0007` | ML-KEM-768 encapsulate/decapsulate | 50k base |
### Hashing & Commitment Precompiles
### Threshold Signatures
| Address | Name | Description | LP |
|---------|------|-------------|-----|
| `0x0000000000000000000000000000000000000501` | **Poseidon2** | PQ-safe hash commitment | - |
| `0x0000000000000000000000000000000000000502` | **Pedersen** | Elliptic curve commitment (BN254) | - |
| `0x0000000000000000000000000000000000000504` | **Blake3** | Fast hashing (6-17x faster than SHA-3) | - |
| Package | Address | Description | Gas |
|---------|---------|-------------|-----|
| `frost` | `0x0800...0002` | FROST Schnorr threshold verify (secp256k1/Ed25519) | 50k + 5k/signer |
| `cggmp21` | `0x0800...0003` | CGGMP21 threshold ECDSA verify (secp256k1) | 75k + 10k/signer |
| `corona` | `0x0200...000B` | Ring-LWE lattice threshold verify (post-quantum) | 150k + 10k/party |
### Zero-Knowledge Precompiles
### Curves & Signatures
| Address | Name | Description | Gas |
|---------|------|-------------|-----|
| `0x0000000000000000000000000000000000000900` | **ZKVerifier** | Generic ZK proof verification | Variable |
| `0x0000000000000000000000000000000000000901` | **Groth16** | Groth16 SNARK verification | ~200,000 |
| `0x0000000000000000000000000000000000000902` | **PLONK** | PLONK proof verification | ~250,000 |
| `0x0000000000000000000000000000000000000903` | **fflonk** | Optimized PLONK variant | ~180,000 |
| `0x0000000000000000000000000000000000000904` | **Halo2** | Recursive proof verification | ~300,000 |
| `0x0000000000000000000000000000000000000910` | **KZG** | Polynomial commitment (EIP-4844) | ~50,000 |
| `0x0000000000000000000000000000000000000912` | **IPA** | Inner product arguments | ~30,000 |
| `0x0000000000000000000000000000000000000920` | **PrivacyPool** | Confidential transaction pool | ~100,000 |
| `0x0000000000000000000000000000000000000921` | **Nullifier** | Double-spend prevention | ~5,000 |
| `0x0000000000000000000000000000000000000922` | **Commitment** | Commitment verification | ~10,000 |
| `0x0000000000000000000000000000000000000923` | **RangeProof** | Bulletproofs range verification | ~100,000 |
| `0x0000000000000000000000000000000000000930` | **RollupVerify** | ZK rollup batch verification | ~500,000 |
| `0x0000000000000000000000000000000000000931` | **StateRoot** | State root verification | ~50,000 |
| `0x0000000000000000000000000000000000000932` | **BatchProof** | Proof aggregation | ~200,000 |
## Categories
### 1. Access Control Precompiles
These precompiles manage permissions for critical blockchain operations:
#### DeployerAllowList (`0x...0001`)
- **Purpose**: Control which addresses can deploy smart contracts
- **Use Case**: Enterprise/private chains with deployment restrictions
- **Gas Cost**: Minimal (configuration reads)
- **Documentation**: [deployerallowlist/](./deployerallowlist/)
#### TxAllowList (`0x...0002`)
- **Purpose**: Control which addresses can submit transactions
- **Use Case**: Permissioned blockchains, compliance requirements
- **Gas Cost**: Minimal (configuration reads)
- **Documentation**: [txallowlist/](./txallowlist/)
### 2. Economic Precompiles
These precompiles manage blockchain economics and tokenomics:
#### FeeManager (`0x...0003`)
- **Purpose**: Configure gas fees, base fees, and EIP-1559 parameters
- **Use Case**: Dynamic fee adjustment, custom fee models
- **Gas Cost**: Varies by operation
- **Documentation**: [feemanager/](./feemanager/)
- **LP**: [LP-314](../../lps/LPs/lp-314.md)
#### NativeMinter (`0x...0004`)
- **Purpose**: Mint and burn native LUX tokens
- **Use Case**: Bridging, wrapping/unwrapping, supply management
- **Gas Cost**: Proportional to amount
- **Documentation**: [nativeminter/](./nativeminter/)
#### RewardManager (`0x...0005`)
- **Purpose**: Distribute staking and validation rewards
- **Use Case**: Validator compensation, staking yields
- **Gas Cost**: Proportional to recipient count
- **Documentation**: [rewardmanager/](./rewardmanager/)
### 3. Post-Quantum Cryptography Precompiles
These precompiles provide quantum-resistant cryptographic operations per NIST FIPS standards:
#### ML-DSA (`0x...0006`)
- **Purpose**: Verify ML-DSA-65 signatures (FIPS 204 - Dilithium)
- **Security Level**: NIST Level 3 (192-bit equivalent)
- **Key Sizes**:
- Public Key: 1,952 bytes
- Signature: 3,309 bytes
- **Performance**: ~108μs verification on Apple M1
- **Gas Cost**: 100,000 base + 10 gas/byte of message
- **Use Cases**:
- Quantum-safe transaction authorization
- Cross-chain message authentication
- Post-quantum multisig wallets
- **Documentation**: [mldsa/](./mldsa/)
- **LP**: [LP-311](../../lps/LPs/lp-311.md)
- **Solidity Interface**: [mldsa/IMLDSA.sol](./mldsa/IMLDSA.sol)
#### SLH-DSA (`0x...0007`)
- **Purpose**: Verify SLH-DSA signatures (FIPS 205 - SPHINCS+)
- **Security Level**: NIST Level 1-5 (128-256 bit)
- **Key Sizes** (SLH-DSA-128s):
- Public Key: 32 bytes
- Signature: 7,856 bytes
- **Performance**: ~286μs verification on Apple M1
- **Gas Cost**: 15,000 base + 10 gas/byte of message
- **Use Cases**:
- Hash-based quantum-safe signatures
- Long-term signature validity (archival)
- Conservative post-quantum security
- Firmware update verification
- **Documentation**: [slhdsa/](./slhdsa/)
- **LP**: [LP-312](../../lps/LPs/lp-312.md)
- **Solidity Interface**: [slhdsa/ISLHDSA.sol](./slhdsa/ISLHDSA.sol)
#### PQCrypto (`0x...0009`)
- **Purpose**: General post-quantum cryptography operations
- **Operations**:
- ML-KEM-768 key encapsulation (FIPS 203)
- Hybrid classical+PQ operations
- Quantum-safe key exchange
- **Documentation**: [pqcrypto/](./pqcrypto/)
- **LP**: [LP-310](../../lps/LPs/lp-310.md) *(to be created)*
### 4. Interoperability Precompiles
These precompiles enable cross-chain communication and messaging:
#### Warp (`0x...0008`)
- **Purpose**: Cross-chain message signing and verification
- **Features**:
- BLS signature aggregation
- Validator attestations
- Cross-chain asset transfers
- **Performance**: ~1.5ms per BLS verification
- **Gas Cost**: Variable based on validator set size
- **Use Cases**:
- Cross-chain token transfers
- Multi-chain contract calls
- Subnet synchronization
- **Documentation**: [warp/](./warp/)
- **LP**: [LP-313](../../lps/LPs/lp-313.md) *(to be created)*
### 5. Threshold Signature Precompiles
Multi-party computation and threshold signatures for custody and consensus:
#### Corona (`0x...000B`)
- **Purpose**: Lattice-based threshold signature verification
- **Algorithm**: LWE-based two-round threshold scheme
- **Security**: Post-quantum (Ring Learning With Errors)
- **Gas Cost**: 150,000 base + 10,000 per party
- **Use Cases**:
- Quantum-safe threshold wallets
- Distributed validator signing
- Post-quantum consensus
- Multi-party custody
- **Documentation**: [corona/](./corona/)
- **LP**: [LP-320](../../lps/LPs/lp-320.md)
#### FROST (`0x...000C`)
- **Purpose**: Schnorr/EdDSA threshold signature verification
- **Algorithm**: FROST (Flexible Round-Optimized Schnorr Threshold)
- **Standards**: IETF FROST, BIP-340/341 (Taproot)
- **Gas Cost**: 50,000 base + 5,000 per signer
- **Signature Size**: 64 bytes (compact Schnorr)
- **Use Cases**:
- Bitcoin Taproot multisig
- Ed25519 threshold (Solana, Cardano, TON)
- Schnorr aggregate signatures
- Lightweight threshold custody
- **Documentation**: [frost/](./frost/)
- **LP**: [LP-321](../../lps/LPs/lp-321.md)
#### CGGMP21 (`0x...000D`)
- **Purpose**: Modern ECDSA threshold signature verification
- **Algorithm**: CGGMP21 with identifiable aborts
- **Security**: Detects malicious parties
- **Gas Cost**: 75,000 base + 10,000 per signer
- **Signature Size**: 65 bytes (standard ECDSA)
- **Use Cases**:
- Ethereum threshold wallets
- Bitcoin threshold multisig
- MPC custody solutions
- Enterprise key management
- **Documentation**: [cggmp21/](./cggmp21/)
- **LP**: [LP-322](../../lps/LPs/lp-322.md)
### 6. Hashing Precompiles
Fast cryptographic hashing for Merkle trees and commitments:
#### Blake3 (`0x0504`)
- **Purpose**: High-performance hashing (6-17x faster than SHA-3)
- **Operations**:
- `hash256`: Standard 256-bit hash
- `hash512`: Extended 512-bit hash
- `hashXOF`: Extensible output function (arbitrary length)
- `hashWithDomain`: Domain-separated hashing
- `merkleRoot`: Batch Merkle tree computation
- `deriveKey`: KDF key derivation
- **Gas Cost**: 100 base + 3-5 gas/word
- **Use Cases**:
- ZK Merkle trees
- Content addressing
- Key derivation
- **GPU Acceleration**: Metal shaders available
- **Documentation**: [blake3/](./blake3/)
- **Solidity Interface**: [blake3/IBlake3.sol](./blake3/IBlake3.sol)
#### Poseidon2 (`0x0501`)
- **Purpose**: ZK-friendly hash function (post-quantum safe)
- **Gas Cost**: ~5,000 per hash
- **Use Cases**: ZK circuits, commitments
#### Pedersen (`0x0502`)
- **Purpose**: Elliptic curve commitment on BN254
- **Gas Cost**: ~10,000 per commitment
- **Note**: NOT post-quantum safe (discrete log)
- **GPU Acceleration**: Metal shaders available
### 7. Zero-Knowledge Precompiles
Comprehensive ZK proof verification and privacy operations:
#### ZK Verifier (`0x0900`)
- **Purpose**: Generic ZK proof verification router
- **Features**:
- Verifying key registration
- Multi-proof-system support
- Verification statistics
- **Documentation**: [zk/](./zk/)
- **Solidity Interface**: [zk/IZK.sol](./zk/IZK.sol)
#### Groth16 (`0x0901`)
- **Purpose**: Groth16 SNARK verification
- **Gas Cost**: ~200,000 per verification
- **Proof Size**: 128 bytes (2 G1 + 1 G2)
- **Trusted Setup**: Circuit-specific
- **GPU Acceleration**: BN254 pairing via Metal
#### PLONK (`0x0902`)
- **Purpose**: Universal PLONK verification
- **Gas Cost**: ~250,000 per verification
- **Proof Size**: ~1KB (variable)
- **Trusted Setup**: Universal (one-time)
#### fflonk (`0x0903`)
- **Purpose**: Optimized PLONK variant
- **Gas Cost**: ~180,000 per verification
- **Improvements**: Faster verification, smaller proofs
#### Halo2 (`0x0904`)
- **Purpose**: Recursive proof composition
- **Gas Cost**: ~300,000 per verification
- **Trusted Setup**: None required
- **Use Cases**: IVC, recursive rollups
#### KZG (`0x0910`)
- **Purpose**: Polynomial commitments (EIP-4844)
- **Gas Cost**: ~50,000 per evaluation
- **Use Cases**: Blob commitments, data availability
- **GPU Acceleration**: FFT and MSM via Metal
#### Privacy Pool (`0x0920`)
- **Purpose**: Confidential transaction pool
- **Features**: Merkle tree, deposit/withdraw
- **Gas Cost**: ~100,000 per operation
#### Nullifier (`0x0921`)
- **Purpose**: Double-spend prevention
- **Gas Cost**: ~5,000 per lookup
#### RangeProof (`0x0923`)
- **Purpose**: Bulletproofs range verification
- **Gas Cost**: ~100,000 per proof
- **Use Cases**: Confidential amounts
#### RollupVerify (`0x0930`)
- **Purpose**: ZK rollup batch verification
- **Gas Cost**: ~500,000 per batch
- **Features**:
- Rollup registration
- Batch verification
- State root tracking
- Challenge support
### 8. Consensus Precompiles
Advanced consensus and validation operations:
#### Quasar (`0x...000A`)
- **Purpose**: Advanced consensus operations for Quasar hybrid consensus
- **Features**:
- Dual certificate verification (classical + PQ)
- BLS signature aggregation
- Hybrid BLS+ML-DSA verification
- Verkle witness verification
- **Documentation**: [quasar/](./quasar/)
- **LP**: [LP-99](../../lps/LPs/lp-99.md)
## Implementation Structure
Each precompile directory contains:
```
<precompile-name>/
├── module.go # Precompile module registration
├── contract.go # Core precompile implementation
├── contract_test.go # Go test suite
├── config.go # Configuration structures (if applicable)
├── config_test.go # Configuration tests
├── I<Name>.sol # Solidity interface
├── contract.abi # ABI definition (if applicable)
└── README.md # Detailed documentation
```
## Development Guidelines
### Adding a New Precompile
1. **Choose an Address**: Select next available address in sequence
2. **Create Directory**: `mkdir -p src/precompiles/<name>`
3. **Implement Interface**: Must implement `StatefulPrecompiledContract`
4. **Write Tests**: Minimum 80% code coverage
5. **Create Solidity Interface**: Include full documentation
6. **Write LP**: Document specification in lps/LPs/
7. **Update This README**: Add to address table and category
### Required Interfaces
All precompiles must implement:
```go
type StatefulPrecompiledContract interface {
// Address returns the precompile address
Address() common.Address
// RequiredGas calculates gas cost for input
RequiredGas(input []byte) uint64
// Run executes the precompile logic
Run(
accessibleState AccessibleState,
caller common.Address,
addr common.Address,
input []byte,
suppliedGas uint64,
readOnly bool,
) ([]byte, uint64, error)
}
```
### Module Registration
Each precompile must provide a module for registration:
```go
type module struct {
address common.Address
contract StatefulPrecompiledContract
}
func (m *module) Address() common.Address {
return m.address
}
func (m *module) Contract() StatefulPrecompiledContract {
return m.contract
}
```
### Gas Calculation Guidelines
Gas costs should reflect:
1. **Computational complexity**: Higher for crypto operations
2. **Memory usage**: Larger for big inputs/outputs
3. **State access**: More for state reads/writes
4. **Benchmarks**: Based on real performance measurements
Example gas formulas:
- **Simple state read**: ~2,000 gas
- **Cryptographic verification**: 50,000 - 500,000 gas
- **Per-byte processing**: 10 - 50 gas/byte
- **State writes**: ~20,000 gas per slot
## Testing Requirements
All precompiles must have:
1. **Unit Tests** (`contract_test.go`):
- Valid input cases
- Invalid input cases
- Edge cases
- Gas calculation verification
2. **Solidity Tests**:
- Interface usage examples
- Integration with other contracts
- Gas benchmarks
3. **Benchmarks**:
- Performance measurements
- Gas cost validation
- Comparison with pure Solidity implementation
## Security Considerations
### Input Validation
- **Always** validate input length before parsing
- Check for buffer overflows
- Validate all parameters against constraints
### Gas Limits
- Ensure gas costs prevent DoS attacks
- Test with maximum-size inputs
- Verify gas calculations don't overflow
### State Access
- Only modify state in non-read-only calls
- Validate caller permissions for privileged operations
- Ensure atomic state updates
### Cryptographic Operations
- Use constant-time implementations when possible
- Validate all cryptographic inputs
- Check signature/key sizes match expected values
- Test against known attack vectors
## Performance Benchmarks
Performance targets on Apple M1 (reference hardware):
### Signature Verification
| Operation | Target | Current |
|-----------|--------|---------|
| ML-DSA-65 Verify | < 150μs | ~108μs ✓ |
| SLH-DSA-192s Verify | < 20ms | ~15ms ✓ |
| BLS Signature Verify | < 2ms | ~1.5ms ✓ |
| FROST (3-of-5) | < 100μs | ~55μs ✓ |
| CGGMP21 (3-of-5) | < 150μs | ~80μs ✓ |
### ZK Proof Verification
| Operation | CPU | GPU (Metal) | Speedup |
|-----------|-----|-------------|---------|
| Groth16 Verify | 12ms | 1.5ms | 8x |
| PLONK Verify | 18ms | 2ms | 9x |
| KZG Point Eval | 3ms | 0.4ms | 7.5x |
| Range Proof (64-bit) | 8ms | 1ms | 8x |
| MSM (256 points) | 45ms | 3ms | 15x |
| FFT (2^16) | 120ms | 8ms | 15x |
| Package | Address | Description | Gas |
|---------|---------|-------------|-----|
| `sr25519` | `0x0A00...0001` | Schnorrkel verify for Substrate→EVM migration | 9k + 3/byte |
| `ed25519` | `0x3211...0000` | Ed25519 signature verify | 3k |
| `secp256r1` | `0x0100` | P-256 ECDSA verify (WebAuthn/passkeys) | 3.5k |
### Hashing
| Operation | Target | Current |
|-----------|--------|---------|
| Blake3 256-bit | < 1μs/KB | ~0.3μs/KB ✓ |
| Blake3 Merkle (1K leaves) | < 100μs | ~45μs ✓ |
| Poseidon2 | < 10μs | ~5μs ✓ |
| Package | Address | Description | Gas |
|---------|---------|-------------|-----|
| `blake3` | `0x0500...0004` | Blake3 hash, Merkle root, KDF, XOF | 100 + 3–5/word |
| `kzg4844` | `0xB002` | KZG polynomial commitment (EIP-4844) | 50k |
### State Operations
### Privacy & ZK
| Operation | Target | Current |
|-----------|--------|---------|
| State Read | < 5μs | ~2μs ✓ |
| State Write | < 10μs | ~5μs ✓ |
| Package | Address | Description | Gas |
|---------|---------|-------------|-----|
| `zk` | `0x0900` | ZK proof verification (Groth16, PLONK, fflonk, Halo2) | 180k–500k |
| `fhe` | — | Fully homomorphic encryption ops | variable |
| `ring` | `0x9202` | Ring signature verification | variable |
| `ecies` | `0x9201` | ECIES encryption/decryption | variable |
| `hpke` | `0x9200` | Hybrid public key encryption | variable |
## Documentation Standards
### DEX
Each precompile must document:
| Package | Address | Description | Gas |
|---------|---------|-------------|-----|
| `dex` | `0x0400...0000` | Native DEX (PoolManager, Router, Hooks, Lending) | variable |
1. **Purpose and Use Cases**: Why it exists, when to use it
2. **Input/Output Format**: Exact byte layouts with examples
3. **Gas Costs**: Formula and examples
4. **Error Conditions**: All possible failure modes
5. **Security Considerations**: Potential vulnerabilities
6. **Examples**: Both Go and Solidity usage
### Infrastructure
## References
| Package | Address | Description | Gas |
|---------|---------|-------------|-----|
| `ai` | `0x0300...0000` | AI mining (ML-DSA verify, TEE attestation, rewards) | variable |
| `quasar` | — | Hybrid consensus certificate verification | variable |
| `dead` | `0x0000...0000` | Dead address interceptor | minimal |
| `graph` | — | GraphQL query precompile | variable |
| `bridge` | — | Cross-chain bridge verification | variable |
| `threshold` | — | Threshold key management | variable |
| `attestation` | — | TEE/GPU attestation | variable |
- **Lux Precompile Standards (LPS)**: [../lps/](../../lps/)
- **EVM Precompiles**: [../evm/](../../evm/)
- **Solidity Interfaces**: [./*/I*.sol](.)
- **NIST PQC Standards**: https://csrc.nist.gov/projects/post-quantum-cryptography
### Support Packages
| Package | Purpose |
|---------|---------|
| `contract` | Core interfaces (`StatefulPrecompiledContract`, `AccessibleState`) |
| `modules` | Module registration system and reserved address ranges |
| `precompileconfig` | Config interfaces (`Upgrade`, `Timestamp`, `IsDisabled`) |
| `registry` | Address-to-LP mapping |
## Structure
Each precompile follows this pattern:
```
<name>/
├── contract.go # Run(), RequiredGas(), Address()
├── contract_test.go # Tests with known vectors
├── module.go # init() → modules.RegisterModule()
└── I<Name>.sol # Solidity interface (optional)
```
## Adding a Precompile
1. Pick an address in a [reserved range](modules/registerer.go)
2. Implement `contract.StatefulPrecompiledContract`
3. Register via `modules.RegisterModule()` in `init()`
4. Add tests (valid, invalid, gas, edge cases)
5. Wire into your L1 via `PrecompileOverrider` or geth's `LuxPrecompiles()`
## Building
```bash
go build ./...
go test ./...
go test -bench=. ./sr25519/ # benchmark a specific package
```
CGO is required for `sr25519` (sr25519-donna C library). All other packages are pure Go.
## License
Copyright (C) 2025, Lux Industries, Inc. All rights reserved.
See the file [LICENSE](../../LICENSE) for licensing terms.
-283
View File
@@ -1,283 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
/**
* @title ITeleportBridge
* @notice Interface for the Teleport Bridge precompile at address 0x0301
* @dev Enables cross-chain AI token transfers from Hanzo L1 to supported EVMs
*
* Supported destination chains:
* - Hanzo EVM: Chain ID 36963
* - Zoo EVM: Chain ID 200200
* - Lux C-Chain: Chain ID 43114
*
* References:
* - LP-2000: AI Mining Standard
* - HIP-006: Hanzo AI Mining Protocol
* - ZIP-005: Zoo AI Mining Integration
*/
interface ITeleportBridge {
// ============ Structs ============
struct TeleportTransfer {
bytes32 teleportId; // Unique transfer identifier
uint256 sourceChain; // Source chain ID (always Hanzo L1 = 0)
uint256 destChain; // Destination chain ID
bytes32 senderPkHash; // BLAKE3 hash of sender's ML-DSA public key
address recipient; // Recipient address on destination chain
uint256 amount; // AI token amount in atomic units
uint64 timestamp; // Transfer initiation timestamp
TransferStatus status; // Current transfer status
}
enum TransferStatus {
Pending, // Awaiting claim on destination
Claimed, // Successfully claimed
Expired, // Claim window passed (24 hours)
Cancelled // Cancelled by sender (L1 only)
}
// ============ Events ============
/// @notice Emitted when a new teleport is received from Hanzo L1
event TeleportReceived(
bytes32 indexed teleportId,
uint256 indexed sourceChain,
address indexed recipient,
uint256 amount
);
/// @notice Emitted when a teleport is claimed
event TeleportClaimed(
bytes32 indexed teleportId,
address indexed claimer,
uint256 amount
);
/// @notice Emitted when a teleport expires
event TeleportExpired(
bytes32 indexed teleportId,
address indexed recipient,
uint256 amount
);
// ============ View Functions ============
/**
* @notice Get the current chain's ID
* @return The chain ID
*/
function getChainId() external view returns (uint256);
/**
* @notice Check if a chain is supported for teleport
* @param chainId The chain ID to check
* @return True if chain is supported
*/
function isSupportedChain(uint256 chainId) external view returns (bool);
/**
* @notice Get all supported chain IDs
* @return Array of supported chain IDs
*/
function getSupportedChains() external view returns (uint256[] memory);
/**
* @notice Get teleport transfer details
* @param teleportId The transfer ID
* @return transfer The transfer details
*/
function getTeleport(bytes32 teleportId) external view returns (TeleportTransfer memory transfer);
/**
* @notice Get all pending teleports for a recipient
* @param recipient The recipient address
* @return Array of pending teleport IDs
*/
function getPendingTeleports(address recipient) external view returns (bytes32[] memory);
/**
* @notice Get total amount of pending teleports for a recipient
* @param recipient The recipient address
* @return Total pending amount
*/
function getPendingAmount(address recipient) external view returns (uint256);
/**
* @notice Check if a teleport is claimable
* @param teleportId The transfer ID
* @return True if transfer can be claimed
*/
function isClaimable(bytes32 teleportId) external view returns (bool);
/**
* @notice Get the claim deadline for a teleport
* @param teleportId The transfer ID
* @return Unix timestamp of claim deadline
*/
function getClaimDeadline(bytes32 teleportId) external view returns (uint256);
// ============ State-Changing Functions ============
/**
* @notice Claim a teleport transfer
* @param teleportId The transfer to claim
* @return amount The claimed amount
*
* Requirements:
* - Transfer must exist and be pending
* - Caller must be the designated recipient
* - Must be within 24-hour claim window
*/
function claim(bytes32 teleportId) external returns (uint256 amount);
/**
* @notice Batch claim multiple teleports
* @param teleportIds Array of transfer IDs
* @return totalAmount Total amount claimed
*/
function batchClaim(bytes32[] calldata teleportIds) external returns (uint256 totalAmount);
/**
* @notice Claim all pending teleports for caller
* @return totalAmount Total amount claimed
* @return claimedCount Number of teleports claimed
*/
function claimAll() external returns (uint256 totalAmount, uint256 claimedCount);
}
/**
* @title TeleportBridgePrecompile
* @notice Wrapper contract for the Teleport Bridge precompile
*/
contract TeleportBridgePrecompile {
/// @notice The precompile address
address public constant PRECOMPILE_ADDRESS = address(0x0301);
/// @notice Hanzo L1 chain identifier (source of all teleports)
uint256 public constant HANZO_L1_CHAIN_ID = 0;
/// @notice Supported destination chain IDs
uint256 public constant HANZO_EVM_CHAIN_ID = 36963;
uint256 public constant ZOO_EVM_CHAIN_ID = 200200;
uint256 public constant LUX_CCHAIN_CHAIN_ID = 96369;
/// @notice Claim window duration (24 hours)
uint256 public constant CLAIM_WINDOW = 24 hours;
// ============ Errors ============
error PrecompileCallFailed();
error TeleportNotFound();
error TeleportNotClaimable();
error NotRecipient();
error ClaimWindowExpired();
// ============ Events ============
event ClaimedViaWrapper(
bytes32 indexed teleportId,
address indexed claimer,
uint256 amount
);
// ============ External Functions ============
/**
* @notice Get current chain ID
*/
function chainId() external view returns (uint256) {
return block.chainid;
}
/**
* @notice Check if running on a supported chain
*/
function onSupportedChain() external view returns (bool) {
return block.chainid == HANZO_EVM_CHAIN_ID ||
block.chainid == ZOO_EVM_CHAIN_ID ||
block.chainid == LUX_CCHAIN_CHAIN_ID;
}
/**
* @notice Claim teleport with validation
*/
function claimTeleport(bytes32 teleportId) external returns (uint256 amount) {
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.call(
abi.encodeWithSelector(ITeleportBridge.claim.selector, teleportId)
);
if (!success) revert PrecompileCallFailed();
amount = abi.decode(result, (uint256));
emit ClaimedViaWrapper(teleportId, msg.sender, amount);
return amount;
}
/**
* @notice Get all pending teleports for caller
*/
function myPendingTeleports() external view returns (bytes32[] memory) {
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
abi.encodeWithSelector(ITeleportBridge.getPendingTeleports.selector, msg.sender)
);
if (!success) revert PrecompileCallFailed();
return abi.decode(result, (bytes32[]));
}
/**
* @notice Get total pending amount for caller
*/
function myPendingAmount() external view returns (uint256) {
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.staticcall(
abi.encodeWithSelector(ITeleportBridge.getPendingAmount.selector, msg.sender)
);
if (!success) revert PrecompileCallFailed();
return abi.decode(result, (uint256));
}
/**
* @notice Claim all pending teleports
*/
function claimAllPending() external returns (uint256 totalAmount, uint256 count) {
(bool success, bytes memory result) = PRECOMPILE_ADDRESS.call(
abi.encodeWithSelector(ITeleportBridge.claimAll.selector)
);
if (!success) revert PrecompileCallFailed();
return abi.decode(result, (uint256, uint256));
}
}
/**
* @title TeleportReceiver
* @notice Abstract contract for receiving teleported AI tokens
* @dev Inherit this contract to add teleport receiving capabilities
*/
abstract contract TeleportReceiver {
ITeleportBridge public immutable teleportBridge;
constructor(address _bridge) {
teleportBridge = ITeleportBridge(_bridge);
}
/**
* @notice Called after a teleport is claimed
* @dev Override to implement custom logic
*/
function onTeleportReceived(
bytes32 teleportId,
uint256 amount
) internal virtual;
/**
* @notice Claim teleport and trigger callback
*/
function receiveTeleport(bytes32 teleportId) external returns (uint256 amount) {
amount = teleportBridge.claim(teleportId);
onTeleportReceived(teleportId, amount);
return amount;
}
}