1.22.2 killed the forged certificate but secured only verification, not
registration — and that is where the CTO's bar, "unique signers + PoP," lives. A
red review confirmed two registration attacks with running PoCs:
- one secret key registered under many node ids clears nova_signer_floor, which
was counting ids and not signers — a stake-majority holder self-finalizes
Nova alone, the exact fork class the floor exists to prevent;
- an honest validator's PUBLISHED key can be registered by a third party and
its genuine ACCEPT replayed, because key_validate proves the point is on the
curve and nothing about who holds the secret.
ValidatorSet::insert now takes a proof of possession and enforces both halves:
- a public key belongs to at most one node (an `owner` index), so a floor on
distinct voters is a floor on distinct signers;
- the registrant signs its own (node ‖ key) under a POP-specific DST
(BLS_POP_..._POP_, distinct from the vote DST), verified against the key at
registration. A key the registrant does not hold — an honest validator's, or
a g1·x − Σpk cancelling key — cannot be registered in its name, because the
proof cannot be made. remove and insert_unkeyed free the key so rotation is
remove-then-insert and a retired key does not stay live.
Two more from the same review:
- HIGH: finality was keyed on the transport block_id, which is unsigned, so a
verified certificate could be relabelled to a block it never attested.
Position::signed_identity returns the value the votes actually committed to
(the canonical id, or block_id only in the degrade where none is set), and
the engine keys finality on that. Two positions that sign to the same bytes
now resolve to one entry, not two.
- MED: verify()'s doc claimed it was "the whole rule on an equal-stake chain."
It is not — its threshold is a field of the certificate, so alone it clears a
1-of-n cert that declares threshold 1. The doc now says so, and names
verify_weighted as the accept rule.
The rogue-key suite is reframed to the stronger truth: the rogue is refused at
REGISTRATION now, one step before the per-signature backstop. cert_conformance
regenerates each Go key from its seed to form the proof, which also asserts Go's
SecretKeyFromSeed and this crate's key_gen derive one key from one seed.
This is a BREAKING registration API (insert and add_validator_with_key take a
proof), so it is 1.22.3 and NOT published — the published 1.22.2 stays the
non-PoP code, no version shares two codebases. Rolling PoP to the Go oracle and
the C++ port is a coordinated, fork-class change and the CTO's call; this branch
does not touch mainnet Go. The proof-of-possession scheme is stated exactly so
Go and C++ can implement it byte-identically: message = node(32) ‖ pubkey(48),
ciphersuite BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_, min_pk (pk G1, sig G2).
Still open before validator-eligible: the Go/C++ PoP rollout, a wire codec with
full-vector conformance, and the Quasar signer-floor decision (unchanged here,
to stay faithful to the Go oracle).
Co-authored-by: Hanzo Dev <[email protected]>
Lux Consensus Source Code Organization
This directory contains implementations of the Lux consensus framework in multiple programming languages. Each language implementation provides the same consensus algorithms with language-specific optimizations and idioms.
Directory Structure
src/
├── c/ # C implementation (high-performance, minimal overhead)
├── cpp/ # C++ implementation with MLX extensions (GPU acceleration)
├── go/ # Go implementation (production blockchain integration)
├── python/ # Python implementation (research and prototyping)
└── rust/ # Rust implementation (memory-safe systems programming)
Language Implementations
Go (/src/go/)
- Status: Production-ready
- Use Case: Core blockchain node integration
- Import Path:
github.com/luxfi/consensus(via go.work at root) - Features: Full integration with Lux node, concurrent processing
C (/src/c/)
- Status: Data structures only — not real consensus (per SDK audit)
- Use Case: Embedded systems, performance-critical applications
- Features: Minimal dependencies, ZeroMQ networking, SIMD optimizations
Rust (/src/rust/)
- Status: FFI wrapper around the C library — inherits C limitations, not native consensus (per SDK audit)
- Use Case: Memory-safe systems, async applications
- Features: Zero-cost abstractions, async/await, compile-time guarantees
Python (/src/python/)
- Status: Research/Development
- Use Case: Prototyping, research, data analysis
- Features: NumPy integration, ML frameworks, visualization
C++ (/src/cpp/)
- Status: Development
- Use Case: High-performance with GPU acceleration
- Features: MLX extensions, template metaprogramming, SIMD/GPU support
Building
From the repository root:
# Build all implementations
make build
# Build specific language
make build-go
make build-c
make build-rust
make build-python
make build-cpp
Testing
From the repository root:
# Test all implementations
make test
# Test specific language
make test-go
make test-c
make test-rust
make test-python
make test-cpp
Consensus Engines
All implementations support these consensus engines (Quasar family):
- Wave - Threshold voting with fast probabilistic consensus (production)
- Nova - Linear chain consensus (wraps Ray sub-protocol)
- Nebula - DAG consensus with safe-prefix commit (wraps Field sub-protocol)
- PostQuantum - Quantum-resistant consensus with BLS + Pulsar + ML-DSA
- Chain - Linear chain consensus for ordered blocks
- DAG - Full directed acyclic graph consensus
Performance Benchmarks
| Implementation | Votes/Second | Memory Usage | Latency |
|---|---|---|---|
| C | 14,000+ | < 10 MB | < 1ms |
| Rust | 13,500+ | < 15 MB | < 1ms |
| Go | 12,000+ | < 20 MB | < 2ms |
| C++ (w/ MLX) | 15,000+ | < 25 MB | < 1ms |
| Python | 5,000+ | < 50 MB | < 5ms |
Note. These per-implementation votes/sec figures are unverified and, per the SDK audit, several measure data-structure insertion on stub/wrapper SDKs (C = data structures only, Rust = FFI wrapper over C, C++ = Wave-only stub); only the Python SDK implements real consensus. Treat as illustrative, not measured consensus throughput. See
.github/workflows/README.mdand the "Honest Assessment" block inLLM.md.
Protocol Compatibility
All implementations use the same binary protocol for network communication:
┌─────────────┬────────────┬──────────┬───────────┬──────────┐
│ Engine Type │ Node ID │ Block ID │ Vote Type │ Reserved │
│ (1 byte) │ (2 bytes) │ (2 bytes)│ (1 byte) │ (2 bytes)│
└─────────────┴────────────┴──────────┴───────────┴──────────┘
This ensures interoperability between different language implementations.
Development Guidelines
- Consistency: All implementations should provide the same consensus guarantees
- Testing: Each implementation must have comprehensive test coverage
- Documentation: Language-specific documentation in
docs/{language}/ - Performance: Optimize for language strengths while maintaining correctness
- Compatibility: Maintain protocol compatibility across all implementations
Contributing
When adding features or fixes:
- Implement in the reference implementation (Go)
- Port to other languages maintaining consistency
- Add tests for all implementations
- Update documentation
See CONTRIBUTING.md for detailed guidelines.
License
Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.