warp

package module
v1.18.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 24, 2025 License: BSD-3-Clause Imports: 19 Imported by: 15

README

Lux Warp V2 Message Format

An enhanced cross-chain messaging (XCM) format with post-quantum safety and private messaging capabilities.

Overview

Warp V2 builds upon the original Warp protocol developed by the Lux team, adding post-quantum cryptography through random ringtail validation and private messaging via Z-chain FHE. It defines a message format and cryptographic standard for secure cross-chain communication that is:

  • Protocol-First: Clean separation between protocol definitions and implementations
  • Language-Agnostic: Core protocol can be implemented in any language (Go, Rust, C++, etc.)
  • Chain-Agnostic: Works with EVM chains, non-EVM chains, and custom VMs
  • Modular: Components can be used independently

Architecture

warp/
├── protocol/           # Protocol definitions (protobuf)
│   ├── message.proto   # Core message types
│   ├── signature.proto # Signature types
│   └── validator.proto # Validator set definitions
├── types/              # Go type definitions
│   ├── message.go      # Message interfaces
│   ├── signature.go    # Signature interfaces
│   └── validator.go    # Validator interfaces
├── crypto/             # Cryptographic primitives
│   ├── bls/            # BLS signature implementation
│   └── hash/           # Hashing utilities
├── backend/            # Backend interface for message handling
├── handlers/           # Network request handlers
└── validators/         # Validator set management

Message Format Specification

The Warp message format uses:

  • BLS Signatures: For efficient multi-signature aggregation
  • Protobuf: For language-agnostic message serialization
  • Content-Addressed: Messages identified by hash
  • Standard Fields: Source chain, destination chain, payload, and optional addressing
  • Optional Privacy: Z-Chain FHE integration for private messages (when available)

Adoption

Warp V2 is designed for easy adoption by any L1 blockchain:

  1. EVM Chains: Implement a simple precompile (see evm/precompile_example.sol)
  2. Non-EVM Chains: Integrate via native modules or system contracts
  3. Privacy Optional: Z-Chain FHE features are opt-in and gracefully degrade

The core message format requires only:

  • 32-byte chain IDs
  • Variable-length payloads
  • BLS signature verification

Usage

Go Implementation
import "github.com/luxfi/warp"

// Create a warp message
msg := warp.NewMessage(sourceChain, destinationChain, payload)

// Sign the message
sig, err := warp.Sign(msg, privateKey)

// Verify signatures
valid := warp.Verify(msg, sig, validatorSet)
Rust Implementation (Future)
use lux_warp::{Message, sign, verify};

// Create a warp message
let msg = Message::new(source_chain, dest_chain, payload);

// Sign the message
let sig = sign(&msg, &private_key)?;

// Verify signatures
let valid = verify(&msg, &sig, &validator_set)?;

Design Principles

  1. Protocol Separation: Core protocol logic is independent of implementation
  2. No Chain Dependencies: The library doesn't depend on specific chain implementations
  3. Extensible: New signature schemes and message types can be added
  4. Performance: Optimized for high-throughput cross-chain messaging
  5. Security: Follows best practices for cryptographic operations

Integration

The library can be integrated with:

  • EVM chains via precompiles
  • Non-EVM chains via native modules
  • Bridge services via RPC/gRPC APIs
  • Off-chain services for message relaying

Documentation

Index

Constants

View Source
const (
	CodecVersion   = 0
	MaxMessageSize = 256 * KiB
)
View Source
const (
	// KiB is 1024 bytes
	KiB = 1024

	// SignatureLen is the length of a BLS signature
	SignatureLen = 96

	// PublicKeyLen is the length of a BLS public key
	PublicKeyLen = 48
)

Constants

View Source
const SignatureHandlerID = 0x12345678

SignatureHandlerID is the protocol ID for warp signature handling

Variables

View Source
var (
	ErrUnexpected          = p2p.ErrUnexpected
	ErrUnregisteredHandler = p2p.ErrUnregisteredHandler
	ErrNotValidator        = p2p.ErrNotValidator
	ErrThrottled           = p2p.ErrThrottled
)

Standard errors re-exported from p2p

View Source
var (
	ErrInvalidSignature   = errors.New("invalid signature")
	ErrInvalidMessage     = errors.New("invalid message")
	ErrUnknownValidator   = errors.New("unknown validator")
	ErrInsufficientWeight = errors.New("insufficient weight")
)
View Source
var (
	ErrWrongSourceChainID = errors.New("wrong SourceChainID")
	ErrWrongNetworkID     = errors.New("wrong networkID")
)
View Source
var Codec = &CodecImpl{}

Codec is the default codec instance

Functions

func AddUint64

func AddUint64(a, b uint64) (uint64, error)

AddUint64 adds two uint64 values and returns an error if overflow

func AggregateSignatures

func AggregateSignatures(signatures []*bls.Signature) (*bls.Signature, error)

AggregateSignatures aggregates multiple signatures into one

func ChainIDToHash

func ChainIDToHash(chainID ids.ID) common.Hash

ChainIDToHash converts a chain ID to a common.Hash

func CheckMulDoesNotOverflow

func CheckMulDoesNotOverflow(a, b uint64) error

CheckMulDoesNotOverflow checks if a * b would overflow uint64

func ComputeHash256

func ComputeHash256(data []byte) []byte

ComputeHash256 computes SHA256 hash

func ComputeHash256Array added in v1.5.0

func ComputeHash256Array(data []byte) [32]byte

ComputeHash256Array computes SHA256 hash and returns as fixed-size array

func MarshalSignatureRequest added in v1.5.0

func MarshalSignatureRequest(req *SignatureRequest) ([]byte, error)

MarshalSignatureRequest marshals a signature request to bytes

func MarshalSignatureResponse added in v1.5.0

func MarshalSignatureResponse(signature []byte) ([]byte, error)

MarshalSignatureResponse marshals a signature response to bytes

func ParsePublicKey

func ParsePublicKey(publicKeyBytes []byte) (*bls.PublicKey, error)

ParsePublicKey parses a BLS public key from bytes

func SerializePublicKey

func SerializePublicKey(publicKey *bls.PublicKey) []byte

SerializePublicKey serializes a BLS public key to bytes

func Sign

func Sign(msg []byte, sk *bls.SecretKey) (*bls.Signature, error)

Sign creates a signature for a message using a secret key

func ValidateValidatorSet

func ValidateValidatorSet(validators []*Validator) error

ValidateValidatorSet performs validation on a validator set

func ValidatorSetToMap

func ValidatorSetToMap(validators []*Validator) map[ids.NodeID]*Validator

ValidatorSetToMap converts a validator slice to a map keyed by node ID

func VerifyMessage

func VerifyMessage(
	msg *Message,
	networkID uint32,
	validatorState ValidatorState,
	quorumNum uint64,
	quorumDen uint64,
) error

VerifyMessage verifies a message against a validator set

func VerifyWeight

func VerifyWeight(signedWeight, totalWeight, quorumNum, quorumDen uint64) error

VerifyWeight verifies that the signed weight meets the quorum threshold

Types

type BitSetSignature

type BitSetSignature struct {
	Signers   Bits                   `serialize:"true"`
	Signature [bls.SignatureLen]byte `serialize:"true"`
}

BitSetSignature is a signature that uses a bit set to indicate which validators signed

func NewBitSetSignature

func NewBitSetSignature(signers Bits, signature [bls.SignatureLen]byte) *BitSetSignature

NewBitSetSignature creates a new bit set signature

func (*BitSetSignature) Bytes added in v0.1.2

func (s *BitSetSignature) Bytes() []byte

Bytes returns the bytes representation of the signature

func (*BitSetSignature) Equal

func (s *BitSetSignature) Equal(other Signature) bool

Equal returns true if two signatures are equal

func (*BitSetSignature) GetSignedWeight

func (s *BitSetSignature) GetSignedWeight(validators []*Validator) (uint64, error)

GetSignedWeight returns the total weight of validators that signed

func (*BitSetSignature) Verify

func (s *BitSetSignature) Verify(msg []byte, validators []*Validator) error

Verify verifies the signature against the message and validator set

type Bits

type Bits []byte

Bits represents a bit set

func NewBitSet

func NewBitSet() Bits

NewBits creates a new bit set

func (*Bits) Add

func (b *Bits) Add(i int)

Add adds an index to the bit set

func (Bits) BitLen

func (b Bits) BitLen() int

BitLen returns the number of bits that can be represented (capacity)

func (*Bits) Clear

func (b *Bits) Clear()

Clear removes all bits from the set

func (Bits) Contains

func (b Bits) Contains(i int) bool

Contains returns true if the bit set contains the index

func (Bits) Difference

func (b Bits) Difference(other Bits) Bits

Difference returns the difference of two bit sets (elements in b but not in other)

func (Bits) Equal

func (b Bits) Equal(other Bits) bool

Equal returns true if two bit sets are equal

func (Bits) HighestSetBit added in v1.4.2

func (b Bits) HighestSetBit() int

HighestSetBit returns the highest bit index that is set + 1 Returns 0 if no bits are set

func (Bits) Intersection

func (b Bits) Intersection(other Bits) Bits

Intersection returns the intersection of two bit sets

func (Bits) Len

func (b Bits) Len() int

Len returns the number of set bits

func (Bits) String

func (b Bits) String() string

String returns a string representation of the bit set

func (Bits) Union

func (b Bits) Union(other Bits) Bits

Union returns the union of two bit sets

type CachedSignatureHandler added in v1.5.0

type CachedSignatureHandler struct {
	// contains filtered or unexported fields
}

CachedSignatureHandler implements a cached handler for warp signatures

func (*CachedSignatureHandler) Request added in v1.5.0

func (h *CachedSignatureHandler) Request(ctx context.Context, nodeID ids.NodeID, deadline time.Time, request []byte) ([]byte, error)

Request handles an incoming signature request with caching

type CanonicalValidatorSet

type CanonicalValidatorSet struct {
	// contains filtered or unexported fields
}

CanonicalValidatorSet represents the canonical ordering of validators

func NewCanonicalValidatorSet

func NewCanonicalValidatorSet(validators []*Validator) (*CanonicalValidatorSet, error)

NewCanonicalValidatorSet creates a new canonical validator set

func (*CanonicalValidatorSet) GetValidator

func (c *CanonicalValidatorSet) GetValidator(index int) (*Validator, error)

GetValidator returns the validator at the given index

func (*CanonicalValidatorSet) Len

func (c *CanonicalValidatorSet) Len() int

Len returns the number of validators

func (*CanonicalValidatorSet) TotalWeight

func (c *CanonicalValidatorSet) TotalWeight() uint64

TotalWeight returns the total weight of all validators

func (*CanonicalValidatorSet) Validators

func (c *CanonicalValidatorSet) Validators() []*Validator

Validators returns the validators in canonical order

type CodecImpl

type CodecImpl struct{}

CodecImpl is used for serializing/deserializing warp messages

func (*CodecImpl) Marshal

func (c *CodecImpl) Marshal(version uint16, v interface{}) ([]byte, error)

Marshal serializes the value

func (*CodecImpl) RegisterType

func (c *CodecImpl) RegisterType(v interface{}) error

RegisterType is a no-op for RLP codec

func (*CodecImpl) Unmarshal

func (c *CodecImpl) Unmarshal(b []byte, v interface{}) (uint16, error)

Unmarshal deserializes the bytes

type Error added in v1.4.2

type Error = p2p.Error

Error is an alias for p2p.Error for backward compatibility

type FakeSender added in v1.4.2

type FakeSender struct{}

FakeSender is a test implementation of Sender that does nothing.

func (FakeSender) SendError added in v1.4.2

func (FakeSender) SendGossip added in v1.4.2

func (FakeSender) SendGossip(context.Context, SendConfig, []byte) error

func (FakeSender) SendRequest added in v1.4.2

func (FakeSender) SendRequest(context.Context, set.Set[ids.NodeID], uint32, []byte) error

func (FakeSender) SendResponse added in v1.4.2

func (FakeSender) SendResponse(context.Context, ids.NodeID, uint32, []byte) error

type Handler added in v1.4.2

type Handler interface {
	// Request handles an incoming request and returns a response or error
	Request(ctx context.Context, nodeID ids.NodeID, requestID uint32, deadline time.Time, msg []byte) ([]byte, *p2p.Error)
	// Response handles an incoming response to a previous request
	Response(ctx context.Context, nodeID ids.NodeID, requestID uint32, msg []byte) error
	// Gossip handles an incoming gossip message
	Gossip(ctx context.Context, nodeID ids.NodeID, msg []byte) error
	// RequestFailed is called when a request fails
	RequestFailed(ctx context.Context, nodeID ids.NodeID, requestID uint32, err *p2p.Error) error
}

Handler handles messages between nodes. This is the primary interface for receiving cross-node messages used by VMs. For simple request/response handlers, use p2p.Handler directly.

type Message

type Message struct {
	UnsignedMessage *UnsignedMessage `serialize:"true"`
	Signature       Signature        `serialize:"true"`
}

Message is a signed warp message

func NewMessage

func NewMessage(unsigned *UnsignedMessage, signature Signature) (*Message, error)

NewMessage creates a new signed message

func ParseMessage

func ParseMessage(b []byte) (*Message, error)

ParseMessage parses a message from bytes

func SignMessage

func SignMessage(
	msg *UnsignedMessage,
	signers []*bls.SecretKey,
	validators []*Validator,
) (*Message, error)

SignMessage signs a warp message with a set of signers

func (*Message) Bytes

func (m *Message) Bytes() []byte

Bytes returns the byte representation of the message

func (*Message) DecodeRLP added in v1.4.2

func (m *Message) DecodeRLP(s *rlp.Stream) error

DecodeRLP implements rlp.Decoder for Message

func (*Message) EncodeRLP added in v1.4.2

func (m *Message) EncodeRLP(w io.Writer) error

EncodeRLP implements rlp.Encoder for Message

func (*Message) Equal

func (m *Message) Equal(other *Message) bool

Equal returns true if two messages are equal

func (*Message) GetSourceChainID added in v1.5.0

func (m *Message) GetSourceChainID() ids.ID

GetSourceChainID returns the source chain ID

func (*Message) ID

func (m *Message) ID() ids.ID

ID returns the ID of the message (hash of unsigned message)

func (*Message) SourceChainIDHash added in v1.5.0

func (m *Message) SourceChainIDHash() common.Hash

SourceChainIDHash returns the source chain ID as a common.Hash (for EVM compatibility)

func (*Message) Verify

func (m *Message) Verify() error

Verify verifies the message format

type NoOpSignatureHandler added in v1.5.0

type NoOpSignatureHandler struct{}

NoOpSignatureHandler is a no-op implementation of SignatureHandler

func (NoOpSignatureHandler) Request added in v1.5.0

Request returns an empty response

type SendConfig added in v1.4.2

type SendConfig = p2p.SendConfig

SendConfig is an alias for p2p.SendConfig for backward compatibility

type Sender added in v1.4.2

type Sender = p2p.Sender

Sender is an alias for p2p.Sender for backward compatibility

type Signature

type Signature interface {
	// Verify verifies the signature against the message and validator set
	Verify(msg []byte, validators []*Validator) error

	// GetSignedWeight returns the total weight of validators that signed
	GetSignedWeight(validators []*Validator) (uint64, error)

	// Equal returns true if two signatures are equal
	Equal(other Signature) bool

	// Bytes returns the bytes representation of the signature
	Bytes() []byte
}

Signature is an interface for warp message signatures

type SignatureAggregator added in v1.5.0

type SignatureAggregator struct {
	// contains filtered or unexported fields
}

SignatureAggregator aggregates validator signatures for warp messages

func NewSignatureAggregator added in v1.5.0

func NewSignatureAggregator(log log.Logger, client *p2p.Client) *SignatureAggregator

NewSignatureAggregator returns an instance of SignatureAggregator

func (*SignatureAggregator) AggregateSignatures added in v1.5.0

func (s *SignatureAggregator) AggregateSignatures(
	ctx context.Context,
	message *Message,
	justification []byte,
	validators []*Validator,
	quorumNum uint64,
	quorumDen uint64,
) (
	_ *Message,
	aggregatedStake *big.Int,
	totalStake *big.Int,
	_ error,
)

AggregateSignatures blocks until quorumNum/quorumDen signatures from validators are requested to be aggregated into a warp message or the context is canceled. Returns the signed message and the amount of stake that signed the message. Caller is responsible for providing a well-formed canonical validator set corresponding to the signer bitset in the message.

type SignatureCacher added in v1.5.0

type SignatureCacher[K comparable, V any] interface {
	Get(key K) (V, bool)
	Put(key K, value V)
}

SignatureCacher provides caching for signature responses

type SignatureHandler added in v1.5.0

type SignatureHandler interface {
	// Request handles an incoming signature request
	Request(ctx context.Context, nodeID ids.NodeID, deadline time.Time, request []byte) ([]byte, error)
}

SignatureHandler handles warp signature requests

func NewCachedSignatureHandler added in v1.5.0

func NewCachedSignatureHandler(cache SignatureCacher[ids.ID, []byte], backend interface{}, signer Signer) SignatureHandler

NewCachedSignatureHandler creates a new cached signature handler

type SignatureHandlerAdapter added in v1.5.0

type SignatureHandlerAdapter struct {
	// contains filtered or unexported fields
}

SignatureHandlerAdapter adapts a SignatureHandler to the p2p.Handler interface. This allows warp signature handlers to be registered with the p2p router.

func NewSignatureHandlerAdapter added in v1.5.0

func NewSignatureHandlerAdapter(handler SignatureHandler) *SignatureHandlerAdapter

NewSignatureHandlerAdapter creates a new adapter that wraps a SignatureHandler and implements the p2p.Handler interface.

func (*SignatureHandlerAdapter) Gossip added in v1.5.0

func (a *SignatureHandlerAdapter) Gossip(ctx context.Context, nodeID ids.NodeID, gossipBytes []byte)

Gossip implements p2p.Handler. Signature handlers do not use gossip.

func (*SignatureHandlerAdapter) Request added in v1.5.0

func (a *SignatureHandlerAdapter) Request(ctx context.Context, nodeID ids.NodeID, deadline time.Time, requestBytes []byte) ([]byte, *p2p.Error)

Request implements p2p.Handler by delegating to the wrapped SignatureHandler.

type SignatureRequest added in v1.5.0

type SignatureRequest struct {
	Message       []byte
	Justification []byte
}

SignatureRequest represents a request for a warp signature

func UnmarshalSignatureRequest added in v1.5.0

func UnmarshalSignatureRequest(data []byte) (*SignatureRequest, error)

UnmarshalSignatureRequest unmarshals bytes to a signature request

type SignatureResponse added in v1.5.0

type SignatureResponse struct {
	Signature []byte
}

SignatureResponse represents a warp signature response

func UnmarshalSignatureResponse added in v1.5.0

func UnmarshalSignatureResponse(data []byte) (*SignatureResponse, error)

UnmarshalSignatureResponse unmarshals bytes to a signature response

type Signer added in v1.4.2

type Signer interface {
	Sign(msg *UnsignedMessage) ([]byte, error)
}

Signer signs warp messages

func NewSigner added in v1.4.2

func NewSigner(sk bls.Signer, networkID uint32, chainID ids.ID) Signer

NewSigner creates a new warp message signer using a bls.Signer interface

type UnsignedMessage

type UnsignedMessage struct {
	NetworkID     uint32 `serialize:"true"`
	SourceChainID ids.ID `serialize:"true"`
	Payload       []byte `serialize:"true"`
}

UnsignedMessage is an unsigned warp message

func NewUnsignedMessage

func NewUnsignedMessage(networkID uint32, sourceChainID ids.ID, payload []byte) (*UnsignedMessage, error)

NewUnsignedMessage creates a new unsigned message

func ParseUnsignedMessage

func ParseUnsignedMessage(b []byte) (*UnsignedMessage, error)

ParseUnsignedMessage parses an unsigned message from bytes

func (*UnsignedMessage) Bytes

func (u *UnsignedMessage) Bytes() []byte

Bytes returns the byte representation of the unsigned message

func (*UnsignedMessage) ID

func (u *UnsignedMessage) ID() ids.ID

ID returns the hash of the unsigned message

func (*UnsignedMessage) Verify

func (u *UnsignedMessage) Verify() error

Verify verifies the unsigned message

type Validator

type Validator struct {
	PublicKey      *bls.PublicKey
	PublicKeyBytes []byte
	Weight         uint64
	NodeID         ids.NodeID
}

Validator represents a validator in the network

func GetCanonicalValidatorSet

func GetCanonicalValidatorSet(
	validatorState ValidatorState,
	chainID ids.ID,
) ([]*Validator, uint64, error)

GetCanonicalValidatorSet retrieves and canonicalizes the validator set

func NewValidator

func NewValidator(
	publicKey *bls.PublicKey,
	publicKeyBytes []byte,
	weight uint64,
	nodeID ids.NodeID,
) *Validator

NewValidator creates a new validator

func (*Validator) Less

func (v *Validator) Less(other *Validator) bool

Less returns true if this validator is less than the other

type ValidatorState

type ValidatorState interface {
	// GetValidatorSet returns the validator set for a given chain ID at a given height
	GetValidatorSet(chainID ids.ID, height uint64) (map[ids.NodeID]*Validator, error)

	// GetCurrentHeight returns the current height
	GetCurrentHeight() (uint64, error)
}

ValidatorState is an interface for retrieving validator sets

type Verifier added in v1.5.0

type Verifier interface {
	// Verify verifies an unsigned warp message with justification.
	// Returns nil on success, or an error if verification fails.
	Verify(ctx context.Context, unsignedMessage *UnsignedMessage, justification []byte) error
}

Verifier verifies warp messages before signing

Directories

Path Synopsis
cmd
plugin
Package warp provides cross-chain messaging functionality for the Lux CLI
Package warp provides cross-chain messaging functionality for the Lux CLI
warpcli command
crypto
fhe
Package fhe provides Fully Homomorphic Encryption interfaces for private messaging.
Package fhe provides Fully Homomorphic Encryption interfaces for private messaging.
ringtail
Package ringtail implements random ringtail validation for post-quantum safety.
Package ringtail implements random ringtail validation for post-quantum safety.
signature
Package signature provides modular signature verification for Warp messages.
Package signature provides modular signature verification for Warp messages.
messages
relayer
signature-aggregator
api
Package types defines the core interfaces for the Warp message format.
Package types defines the core interfaces for the Warp message format.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL