Specification
MLRTHash v1 — Technology
Malairte Bitcoin's proof-of-work algorithm is MLRTHash v1: a deterministic double application of SHA-3-256 (NIST FIPS 202) over a 96-byte serialised block header. This page is the canonical specification.
Block Header
96-byte structure
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | Version (uint32, little-endian) |
| 4 | 32 | PreviousHash (Hash256, raw) |
| 36 | 32 | MerkleRoot (Hash256, raw) |
| 68 | 8 | Timestamp (int64 LE, Unix seconds) |
| 76 | 4 | Bits (uint32 LE, compact target) |
| 80 | 8 | Nonce (uint64 LE) |
| 88 | 8 | Height (uint64 LE) |
Total: exactly 96 bytes. The mining loop varies Nonce (offset 80, 8 bytes); Height is included in the hash so reorgs at different heights produce different work.
Hash Function
Double SHA-3-256
MLRTHash(header) = SHA3-256(SHA3-256(serialize(header)))
Both inner and outer hashes are the standard NIST-finalised SHA-3-256 (Keccak-f[1600] sponge with rate=1088 bits, capacity=512 bits, 24 rounds). The output is interpreted as a 256-bit big-endian unsigned integer for difficulty comparison.
A header is a valid block header iff:
MLRTHash(header) ≤ CompactToBig(header.Bits)
Consensus
Difficulty & retargeting
- Initial difficulty: 1 (bits = 0x207fffff)
- Retarget interval: every 2016 blocks (~67 hours at target)
- Target block time: 120 seconds (2 minutes)
- Adjustment formula: newTarget = oldTarget × actualTime / targetTime, clamped to [1/4, 4] per cycle
- Median-time-past rule: every block timestamp must exceed the median of the prior 11 blocks
Reference Implementation
Go (canonical)
package consensus
import (
"github.com/computervirtualservices/malairte/internal/crypto"
"github.com/computervirtualservices/malairte/internal/primitives"
)
func MLRTHash(header *primitives.BlockHeader) [32]byte {
return crypto.DoubleSHA3256(header.Serialize())
}
func HashMeetsDifficulty(hash [32]byte, bits uint32) bool {
target := CompactToBig(bits)
hashInt := new(big.Int).SetBytes(hash[:])
return hashInt.Cmp(target) <= 0
}
CUDA (GPU)
A self-contained CUDA implementation lives in internal/mining/cuda/mlrt_gpu.cu. It implements Keccak-f[1600] from scratch, specialises SHA-3-256 for 96-byte and 32-byte inputs (the only two sizes used in the mining loop), and runs roughly 16 million nonces per kernel launch.
Verification
Test vectors
Reference outputs produced by the canonical Go implementation and verified byte-for-byte by the CUDA implementation. If your implementation produces these three hashes, it's correct.
| Input | DoubleSHA3-256 output (hex) |
|---|---|
| "" (empty) | a1292c11ccdb876535c6699e8217e1a1294190d83e4233ecc490d32df17a4116 |
| "abc" | f6362cbb9fb8a60f03c2f0d8124d2c6a1a828e2db8e8b05a6f699735b4492cbc |
| 96 zero bytes | 9dcb0d6ee0ade399575e13eaf305066ec61bc65049b94db86f6badf3ae359744 |
Parameters
Consensus constants
| Maximum supply | 21,000,000 MLRT (8 decimals → 2.1 × 10¹⁵ atoms) |
| Initial block reward | 50 MLRT |
| Halving interval | 210,000 blocks |
| Target block time | 120 seconds (2 minutes) |
| Retarget interval | 2016 blocks (~67 hours) |
| Coinbase maturity | 100 blocks |
| Initial max block size | 1 MB serialized |
| Network magic (mainnet) | 0x4d4c5254 ("MLRT") |
| P2P port | 9333 |
| RPC port | 9332 |
| Address format | Base58Check, version byte 50 ("M") |
| Protocol fee | 10 atoms per coinbase + per non-coinbase tx |
Related
Quantum Security →
Why we use SHA-3 and the MLIP-1 post-quantum signature roadmap.
Mining →
CPU and GPU miner setup, pool configuration, hashrate guidance.
Fair Launch →
No premine, no ICO. Verify supply schedule and protocol fee.
Source on GitHub →
Full Malairte Core source — Go reference + CUDA miner.