python-bchlib icon indicating copy to clipboard operation
python-bchlib copied to clipboard

BCH Decode of BCH(255,207, t=6) decode_inplace error

Open caronoff opened this issue 4 years ago • 2 comments

Reopening issue which was accidentally closed before resolution.

This succinctly describes the problem. If you add a single binary byte b'\x01' at the beginning to form data byte array, you get a byte array of 26 which successfully encodes the ecc. However, the decode fails and is locked out at 25 bytes on line bitflips = bch.decode_inplace(data, ecc)

It seems to me that if if encodes 26 bytes (201 bits actually with the \x01 prepended), then it should be able to do a bch.decode_inplace(data, ecc) on the data being same 26 bytes ( 201 bits).

To be clearer, this same issue is in the testing branch. Master branch illustrated same issue as testing, adjusting for syntactic changes.

NB: Note data = bytearray(b'\x01'+os.urandom(25)) works going in for the encoder, but fails for the decoder.

import bchlib import hashlib import os import random

def test_bchlib(): # create a bch object BCH_POLYNOMIAL = 285 BCH_BITS = 6 bch = bchlib.BCH(BCH_POLYNOMIAL, BCH_BITS)

# random data
data = bytearray(b'\x01'+os.urandom(25))
print(len(data))
# encode and make a "packet"
ecc = bch.encode(data)
packet = data + ecc
sha1_initial = hashlib.sha1(packet)
print('sha1: %s' % (sha1_initial.hexdigest(),))

def bitflip(packet):
    byte_num = random.randint(0, len(packet) - 1)
    bit_num = random.randint(0, 7)
    packet[byte_num] ^= (1 << bit_num)

# make BCH_BITS errors
for _ in range(BCH_BITS):
    bitflip(packet)

# print hash of packet
sha1_corrupt = hashlib.sha1(packet)
print('sha1: %s' % (sha1_corrupt.hexdigest(),))

# de-packetize
data, ecc = packet[:-bch.ecc_bytes], packet[-bch.ecc_bytes:]

print(len(data))
# correct
bitflips = bch.decode_inplace(data, ecc)

print('bitflips: %d' % (bitflips))

# packetize
packet = data + ecc

# print hash of packet
sha1_corrected = hashlib.sha1(packet)
print('sha1: %s' % (sha1_corrected.hexdigest(),))

if sha1_initial.digest() == sha1_corrected.digest():
    print('Corrected!')
else:
    print('Failed')

if name == "main": test_bchlib()

 

caronoff avatar Oct 30 '21 15:10 caronoff

I propose the bch.c source file line change to allow missed bits in decode sanity check :

/* sanity check: make sure data length can be handled */ if (8*len > (bch->n-bch->ecc_bits))

Change to

/* sanity check: make sure data length can be handled */ if (8*len -1 > (bch->n-bch->ecc_bits))

In the BCHTestCase class in python,

change this max_data_len = bch.n // 8 - (bch.ecc_bits + 7) // 8

to: max_data_len = bch.n // 8 - (bch.ecc_bits + 7) // 8 + 1

caronoff avatar Oct 31 '21 21:10 caronoff

Is this still an issue with the v1.0.0 API?

jkent avatar Aug 07 '23 19:08 jkent