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