void CBC_ReedSolomonDecoder::Decode(CFX_Int32Array* received, int32_t twoS, int32_t& e) { CBC_ReedSolomonGF256Poly poly; poly.Init(m_field, received, e); BC_EXCEPTION_CHECK_ReturnVoid(e); CFX_Int32Array syndromeCoefficients; syndromeCoefficients.SetSize(twoS); FX_BOOL dataMatrix = FALSE; FX_BOOL noError = TRUE; for (int32_t i = 0; i < twoS; i++) { int32_t eval = poly.EvaluateAt(m_field->Exp(dataMatrix ? i + 1 : i)); syndromeCoefficients[twoS - 1 - i] = eval; if (eval != 0) { noError = FALSE; } } if (noError) { return; } CBC_ReedSolomonGF256Poly syndrome; syndrome.Init(m_field, &syndromeCoefficients, e); BC_EXCEPTION_CHECK_ReturnVoid(e); CBC_ReedSolomonGF256Poly* rsg = m_field->BuildMonomial(twoS, 1, e); BC_EXCEPTION_CHECK_ReturnVoid(e); CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp(rsg); CFX_PtrArray* pa = RunEuclideanAlgorithm(temp.get(), &syndrome, twoS, e); BC_EXCEPTION_CHECK_ReturnVoid(e); CBC_AutoPtr<CFX_PtrArray> sigmaOmega(pa); CBC_AutoPtr<CBC_ReedSolomonGF256Poly> sigma( (CBC_ReedSolomonGF256Poly*)(*sigmaOmega)[0]); CBC_AutoPtr<CBC_ReedSolomonGF256Poly> omega( (CBC_ReedSolomonGF256Poly*)(*sigmaOmega)[1]); CFX_Int32Array* ia1 = FindErrorLocations(sigma.get(), e); BC_EXCEPTION_CHECK_ReturnVoid(e); CBC_AutoPtr<CFX_Int32Array> errorLocations(ia1); CFX_Int32Array* ia2 = FindErrorMagnitudes(omega.get(), errorLocations.get(), dataMatrix, e); BC_EXCEPTION_CHECK_ReturnVoid(e); CBC_AutoPtr<CFX_Int32Array> errorMagnitudes(ia2); for (int32_t k = 0; k < errorLocations->GetSize(); k++) { int32_t position = received->GetSize() - 1 - m_field->Log((*errorLocations)[k], e); BC_EXCEPTION_CHECK_ReturnVoid(e); if (position < 0) { e = BCExceptionBadErrorLocation; BC_EXCEPTION_CHECK_ReturnVoid(e); } (*received)[position] = CBC_ReedSolomonGF256::AddOrSubtract( (*received)[position], (*errorMagnitudes)[k]); } }
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply( CBC_ReedSolomonGF256Poly* other, int32_t& e) { if (IsZero() || other->IsZero()) { CBC_ReedSolomonGF256Poly* temp = m_field->GetZero()->Clone(e); BC_EXCEPTION_CHECK_ReturnValue(e, NULL); return temp; } CFX_Int32Array aCoefficients; aCoefficients.Copy(m_coefficients); int32_t aLength = m_coefficients.GetSize(); CFX_Int32Array bCoefficients; bCoefficients.Copy(*(other->GetCoefficients())); int32_t bLength = other->GetCoefficients()->GetSize(); CFX_Int32Array product; product.SetSize(aLength + bLength - 1); for (int32_t i = 0; i < aLength; i++) { int32_t aCoeff = m_coefficients[i]; for (int32_t j = 0; j < bLength; j++) { product[i + j] = CBC_ReedSolomonGF256::AddOrSubtract( product[i + j], m_field->Multiply(aCoeff, other->GetCoefficients()->operator[](j))); } } CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &product, e); BC_EXCEPTION_CHECK_ReturnValue(e, NULL); return temp; }
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::AddOrSubtract( CBC_ReedSolomonGF256Poly* other, int32_t& e) { if (IsZero()) return other->Clone(e); if (other->IsZero()) return Clone(e); CFX_Int32Array smallerCoefficients; smallerCoefficients.Copy(m_coefficients); CFX_Int32Array largerCoefficients; largerCoefficients.Copy(*(other->GetCoefficients())); if (smallerCoefficients.GetSize() > largerCoefficients.GetSize()) { CFX_Int32Array temp; temp.Copy(smallerCoefficients); smallerCoefficients.Copy(largerCoefficients); largerCoefficients.Copy(temp); } CFX_Int32Array sumDiff; sumDiff.SetSize(largerCoefficients.GetSize()); int32_t lengthDiff = largerCoefficients.GetSize() - smallerCoefficients.GetSize(); for (int32_t i = 0; i < lengthDiff; i++) { sumDiff[i] = largerCoefficients[i]; } for (int32_t j = lengthDiff; j < largerCoefficients.GetSize(); j++) { sumDiff[j] = (CBC_ReedSolomonGF256::AddOrSubtract( smallerCoefficients[j - lengthDiff], largerCoefficients[j])); } CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &sumDiff, e); BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); return temp; }
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply(int32_t scalar, int32_t& e) { if (scalar == 0) return m_field->GetZero()->Clone(e); if (scalar == 1) return Clone(e); int32_t size = m_coefficients.GetSize(); CFX_Int32Array product; product.SetSize(size); for (int32_t i = 0; i < size; i++) { product[i] = m_field->Multiply(m_coefficients[i], scalar); } CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &product, e); BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); return temp; }
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::MultiplyByMonomial( int32_t degree, int32_t coefficient, int32_t& e) { if (degree < 0) { e = BCExceptionDegreeIsNegative; return nullptr; } if (coefficient == 0) return m_field->GetZero()->Clone(e); int32_t size = m_coefficients.GetSize(); CFX_Int32Array product; product.SetSize(size + degree); for (int32_t i = 0; i < size; i++) { product[i] = (m_field->Multiply(m_coefficients[i], coefficient)); } CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &product, e); BC_EXCEPTION_CHECK_ReturnValue(e, nullptr); return temp; }
CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Clone(int32_t& e) { CBC_ReedSolomonGF256Poly* temp = new CBC_ReedSolomonGF256Poly(); temp->Init(m_field, &m_coefficients, e); BC_EXCEPTION_CHECK_ReturnValue(e, NULL); return temp; }