Skip to main content
XHash is a modified version of the Ethash proof-of-work algorithm. It retains Ethash’s memory-hard properties while making existing Ethash ASICs obsolete.

How XHash Works

XHash follows the same high-level principles as Ethash. We recommend reading the Ethash documentation before diving into the differences between the two.

Epoch Definition

XHash uses a different epoch length than Ethash. Ethash’s 30,000-block epoch was designed for Ethereum’s 15-second block times. Since Parallax uses 10-minute blocks, the epoch length has been adjusted to 720 blocks, resulting in approximately the same ~5-day interval between DAG regenerations.
EPOCH_LENGTH = 720  # blocks per epoch

Use of SHA3

Ethereum’s implementation of SHA3 was based on an earlier Keccak draft. During the finalization of the SHA3 standard, the padding rules were changed — meaning Ethereum’s “sha3_256” and “sha3_512” functions are actually Keccak-256 and Keccak-512, not true SHA3. In contrast, XHash uses the finalized NIST SHA3 specifications rather than Keccak variants.
This change improves interoperability with standard cryptographic libraries and eliminates Ethereum’s legacy inconsistency.

Data Aggregation Function

Ethash’s mixing function was inspired by the FNV hash, but not identical to it. XHash replaces this with a direct implementation of FNV-1, which multiplies a prime by each byte (octet) of input data in turn.
FNV_PRIME = 0x01000193

def fnv(a: int, b: int) -> int:
    h = a
    for _ in range(4):  # consume 4 bytes of b (little-endian)
        h *= FNV_PRIME
        h ^= (b & 0xFF)
        b >>= 8
        h &= 0xFFFFFFFF  # constrain to 32-bit range
    return h

Seed Hash Definition

To compute the seed hash used for mining on top of a given block, XHash introduces the following algorithm:
PARALLAX_CHAIN_MAGIC = b"PARALLAX\x01"

def get_seedhash(block)
    s = '\x00' * 32
    for _ in range(block.number // EPOCH_LENGTH):
        s = serialize_hash(sha3_256(PARALLAX_CHAIN_MAGIC + s))
    return s
This differs from the original Ethash implementation by including the Parallax chain magic constant in each epoch iteration, ensuring that Parallax DAGs are network-unique and incompatible with any Ethash chain.

Mining Algorithm

The mining process in XHash is defined as:
def mine(full_size, dataset, header, difficulty):
    # zero-pad target for comparison on the same digit length
    target = zpad(encode_int((2**256 - 1) // difficulty), 64)[::-1]
    from random import randint
    nonce = randint(0, 2**64)
    while hashimoto_full(full_size, dataset, header, nonce) > target:
        nonce = (nonce + 1) % 2**64
    return nonce
The key difference from Ethash lies in the target calculation: Ethash uses 2^256 / difficulty, whereas XHash uses (2^256 - 1) / difficulty. This subtle change aligns the target range more closely with the full 256-bit integer space, ensuring consistent mining behavior across implementations.
I