FAILURE MAP
← Case archive

FA-72051 / Error-correcting codes / Open access

RAID-6 multiplies by g to the i instead of dividing · case 01

Rebuilt blocks are wrong except on disk 0.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The final step multiplies by g^i instead of g^(-i).

THE FAILURE

The final step multiplies by g^i instead of g^(-i).

Unsuccessful approach: Using g^(256 - i) is one power off.

Case contract

Recover one missing data block of a RAID-6 stripe over GF(2^8) (0x11D). data has exactly one None (else None is returned). P = XOR of data; Q = sum of g^k * D_k with g = 2 and k the 0-based disk index. Use P when it is available; otherwise rebuild D_i = (Q + sum over present k of g^k D_k) * g^(-i); if neither is available return None.

Why this case matters

Dual-parity arrays rebuild a data disk from the Q syndrome when the P disk has also failed.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data, p, q):
    EXP, LOG = [0] * 512, [0] * 256
    x = 1
    for i in range(255):
        EXP[i] = EXP[i + 255] = x
        LOG[x] = i
        x <<= 1
        if x & 0x100:
            x ^= 0x11D
    def mul(a, b):
        return 0 if a == 0 or b == 0 else EXP[LOG[a] + LOG[b]]
    
    if data.count(None) != 1:
        return None
    i = data.index(None)
    if p is not None:
        x = p
        for v in data:
            if v is not None:
                x ^= v
        return x
    if q is None:
        return None
    x = q
    for k, v in enumerate(data):
        if v is not None:
            x ^= mul(EXP[k], v)
    return mul(x, EXP[i])
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression [[111, null], null, 186]', [[111, None], None, 186], 228], ['regression [[61, null, 139], null, 236]', [[61, None, 139], None, 236], 237], ['control [[61, null, 139], 91, 236]', [[61, None, 139], 91, 236], 237], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222], ['control [[220, 10, null], 58, 95]', [[220, 10, None], 58, 95], 236], ['control [[114, null, 163, 119, 100, 76], 199, 178]', [[114, None, 163, 119, 100, 76], 199, 178], 73], ['control [[1, 2], null, 3]', [[1, 2], None, 3], None], ['control [[null, null], 1, 2]', [[None, None], 1, 2], None]], [['regression [[104, 202, 220, 113, null], null, 38]', [[104, 202, 220, 113, None], None, 38], 191], ['regression [[10, 11, null, 231, 194, 75], null, 1]', [[10, 11, None, 231, 194, 75], None, 1], 222], ['control [[null, null], 1, 2]', [[None, None], 1, 2], None], ['control [[4, null], null, null]', [[4, None], None, None], None], ['control [[61, null, 139], 91, 236]', [[61, None, 139], 91, 236], 237], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222], ['control [[220, 10, null], 58, 95]', [[220, 10, None], 58, 95], 236], ['control [[114, null, 163, 119, 100, 76], 199, 178]', [[114, None, 163, 119, 100, 76], 199, 178], 73]], [['regression [[220, 10, null], null, 95]', [[220, 10, None], None, 95], 236], ['regression [[68, 12, null, 209], null, 47]', [[68, 12, None, 209], None, 47], 106], ['control [[114, null, 163, 119, 100, 76], 199, 178]', [[114, None, 163, 119, 100, 76], 199, 178], 73], ['control [[1, 2], null, 3]', [[1, 2], None, 3], None], ['control [[null, null], 1, 2]', [[None, None], 1, 2], None], ['control [[4, null], null, null]', [[4, None], None, None], None], ['control [[61, null, 139], 91, 236]', [[61, None, 139], 91, 236], 237], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222]], [['regression [[114, null, 163, 119, 100, 76], null, 178]', [[114, None, 163, 119, 100, 76], None, 178], 73], ['regression [[130, 12, 210, 57, null, 52, 76], null, 198]', [[130, 12, 210, 57, None, 52, 76], None, 198], 161], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222], ['control [[220, 10, null], 58, 95]', [[220, 10, None], 58, 95], 236], ['control [[114, null, 163, 119, 100, 76], 199, 178]', [[114, None, 163, 119, 100, 76], 199, 178], 73], ['control [[1, 2], null, 3]', [[1, 2], None, 3], None], ['control [[null, null], 1, 2]', [[None, None], 1, 2], None], ['control [[4, null], null, null]', [[4, None], None, None], None]], [['regression [[111, null], null, 186]', [[111, None], None, 186], 228], ['regression [[61, null, 139], null, 236]', [[61, None, 139], None, 236], 237], ['partial-repair [[null, 5], null, 7]', [[None, 5], None, 7], 13], ['partial-repair [[null], null, 9]', [[None], None, 9], 9], ['control [[4, null], null, null]', [[4, None], None, None], None], ['control [[61, null, 139], 91, 236]', [[61, None, 139], 91, 236], 237], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222], ['control [[220, 10, null], 58, 95]', [[220, 10, None], 58, 95], 236]]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression [[111, null], null, 186]183228Failed
regression [[61, null, 139], null, 236]147237Failed
control [[61, null, 139], 91, 236]237237Passed
control [[10, 11, null, 231, 194, 75], 177, 1]222222Passed
control [[220, 10, null], 58, 95]236236Passed
control [[114, null, 163, 119, 100, 76], 199, 178]7373Passed
control [[1, 2], null, 3]NoneNonePassed
control [[null, null], 1, 2]NoneNonePassed

SHA-256 / fe94ade53a6e69f6e7853378a894327b664fdce9aded6a4aa66336887de2e41e

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(data, p, q):
    EXP, LOG = [0] * 512, [0] * 256
    x = 1
    for i in range(255):
        EXP[i] = EXP[i + 255] = x
        LOG[x] = i
        x <<= 1
        if x & 0x100:
            x ^= 0x11D
    def mul(a, b):
        return 0 if a == 0 or b == 0 else EXP[LOG[a] + LOG[b]]
    
    if data.count(None) != 1:
        return None
    i = data.index(None)
    if p is not None:
        x = p
        for v in data:
            if v is not None:
                x ^= v
        return x
    if q is None:
        return None
    x = q
    for k, v in enumerate(data):
        if v is not None:
            x ^= mul(EXP[k], v)
    return mul(x, EXP[(256 - i) % 255])
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['regression [[111, null], null, 186]', [[111, None], None, 186], 228], ['regression [[61, null, 139], null, 236]', [[61, None, 139], None, 236], 237], ['control [[61, null, 139], 91, 236]', [[61, None, 139], 91, 236], 237], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222], ['control [[220, 10, null], 58, 95]', [[220, 10, None], 58, 95], 236], ['control [[114, null, 163, 119, 100, 76], 199, 178]', [[114, None, 163, 119, 100, 76], 199, 178], 73], ['control [[1, 2], null, 3]', [[1, 2], None, 3], None], ['control [[null, null], 1, 2]', [[None, None], 1, 2], None]], [['regression [[104, 202, 220, 113, null], null, 38]', [[104, 202, 220, 113, None], None, 38], 191], ['regression [[10, 11, null, 231, 194, 75], null, 1]', [[10, 11, None, 231, 194, 75], None, 1], 222], ['control [[null, null], 1, 2]', [[None, None], 1, 2], None], ['control [[4, null], null, null]', [[4, None], None, None], None], ['control [[61, null, 139], 91, 236]', [[61, None, 139], 91, 236], 237], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222], ['control [[220, 10, null], 58, 95]', [[220, 10, None], 58, 95], 236], ['control [[114, null, 163, 119, 100, 76], 199, 178]', [[114, None, 163, 119, 100, 76], 199, 178], 73]], [['regression [[220, 10, null], null, 95]', [[220, 10, None], None, 95], 236], ['regression [[68, 12, null, 209], null, 47]', [[68, 12, None, 209], None, 47], 106], ['control [[114, null, 163, 119, 100, 76], 199, 178]', [[114, None, 163, 119, 100, 76], 199, 178], 73], ['control [[1, 2], null, 3]', [[1, 2], None, 3], None], ['control [[null, null], 1, 2]', [[None, None], 1, 2], None], ['control [[4, null], null, null]', [[4, None], None, None], None], ['control [[61, null, 139], 91, 236]', [[61, None, 139], 91, 236], 237], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222]], [['regression [[114, null, 163, 119, 100, 76], null, 178]', [[114, None, 163, 119, 100, 76], None, 178], 73], ['regression [[130, 12, 210, 57, null, 52, 76], null, 198]', [[130, 12, 210, 57, None, 52, 76], None, 198], 161], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222], ['control [[220, 10, null], 58, 95]', [[220, 10, None], 58, 95], 236], ['control [[114, null, 163, 119, 100, 76], 199, 178]', [[114, None, 163, 119, 100, 76], 199, 178], 73], ['control [[1, 2], null, 3]', [[1, 2], None, 3], None], ['control [[null, null], 1, 2]', [[None, None], 1, 2], None], ['control [[4, null], null, null]', [[4, None], None, None], None]], [['regression [[111, null], null, 186]', [[111, None], None, 186], 228], ['regression [[61, null, 139], null, 236]', [[61, None, 139], None, 236], 237], ['partial-repair [[null, 5], null, 7]', [[None, 5], None, 7], 13], ['partial-repair [[null], null, 9]', [[None], None, 9], 9], ['control [[4, null], null, null]', [[4, None], None, None], None], ['control [[61, null, 139], 91, 236]', [[61, None, 139], 91, 236], 237], ['control [[10, 11, null, 231, 194, 75], 177, 1]', [[10, 11, None, 231, 194, 75], 177, 1], 222], ['control [[220, 10, null], 58, 95]', [[220, 10, None], 58, 95], 236]]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
regression [[111, null], null, 186]213228Failed
regression [[61, null, 139], null, 236]199237Failed
control [[61, null, 139], 91, 236]237237Passed
control [[10, 11, null, 231, 194, 75], 177, 1]222222Passed
control [[220, 10, null], 58, 95]236236Passed
control [[114, null, 163, 119, 100, 76], 199, 178]7373Passed
control [[1, 2], null, 3]NoneNonePassed
control [[null, null], 1, 2]NoneNonePassed

SHA-256 / 06b5716014a0b247ad4d2f7ebbf3f19cfebbfce9593a33f834df8a8bf4cd68ae

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

Verification & scope

A deterministic, bounded teaching model of the named code under the stated contract; not a production codec. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:48:35.050409+00:00.

Case digest / 3865026d3631939be0ac27f89e80011a05da5de1379658a3d57f79e2ea24ed69