From d60d79aa48f14a5ec75b1c94c4760d17b8d819b9 Mon Sep 17 00:00:00 2001 From: cfif Date: Fri, 24 Jan 2025 13:22:33 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D1=83=D1=8E=20=D0=BE=D1=80?= =?UTF-8?q?=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8E=20GONEC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PolyGalois256.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ PolyGalois256.h | 48 ++++++++++++ modular.json | 17 +++++ 3 files changed, 257 insertions(+) create mode 100644 PolyGalois256.c create mode 100644 PolyGalois256.h create mode 100644 modular.json diff --git a/PolyGalois256.c b/PolyGalois256.c new file mode 100644 index 0000000..7a87cc4 --- /dev/null +++ b/PolyGalois256.c @@ -0,0 +1,192 @@ +// +// Created by zemon on 29.07.2022. +// +#include +#include "PolyGalois256.h" + +inline size_t sPolyGalois256HighestDegree(tPolyGalois256 *poly) { + return poly->length - 1; +} + +void vPolyGalois256Mul(tGalois256 *gf, tPolyGalois256 *first, tPolyGalois256 *second, tPolyGalois256 *result) { + + uint8_t result_degree = sPolyGalois256HighestDegree(first) + sPolyGalois256HighestDegree(second); + result->length = result_degree + 1; + + memset(result->data, 0, result->length); + + for (size_t first_idx = 0; first_idx < first->length; ++first_idx) { + for (size_t second_idx = 0; second_idx < second->length; ++second_idx) { + uint8_t mux_degree = first_idx + second_idx; + uint8_t mux = iGalois256Mul(gf, first->data[first_idx], second->data[second_idx]); + + result->data[mux_degree] = iGalois256Add(gf, result->data[mux_degree], mux); + } + } + +} + +void vPolyGalois256Add(tGalois256 *gf, tPolyGalois256 *first, tPolyGalois256 *second, tPolyGalois256 *result) { + + uint8_t result_degree = first->length > second->length ? first->length : second->length; + result->length = result_degree; + + for (size_t idx = 0; idx < result_degree; ++idx) { + result->data[idx] = 0; + + if (first->length > idx) { + result->data[idx] = iGalois256Add(gf, result->data[idx], first->data[idx]); + } + if (second->length > idx) { + result->data[idx] = iGalois256Add(gf, result->data[idx], second->data[idx]); + } + } + +} + +void vPolyGalois256MulNumber(tGalois256 *gf, tPolyGalois256 *first, uint8_t number, tPolyGalois256 *result) { + + result->length = sPolyGalois256HighestDegree(first) + number; + + memset(result->data, 0, number); + + memcpy(result->data + number, first->data, result->length - number); + +} + + +void vPolyGalois256MulNumberSelf(tGalois256 *gf, tPolyGalois256 *poly, uint8_t number) { + + memmove(poly->data + number, poly->data, poly->length); + memset(poly->data, 0, number); + + poly->length += number; +} + +void vPolyGalois256Scale(tGalois256 *gf, tPolyGalois256 *orgn, uint8_t number, tPolyGalois256 *result) { + result->length = orgn->length; + for (size_t idx = 0; idx < orgn->length; ++idx) { + result->data[idx] = iGalois256Mul(gf, orgn->data[idx], number); + } +} + +void vPolyGalois256Copy(tPolyGalois256 *source, tPolyGalois256 *target) { + target->length = source->length; + memcpy(target->data, source->data, source->length); +} + +void vPolyGalois256CopyRevers(tPolyGalois256 *source, tPolyGalois256 *target) { + target->length = source->length; + + for (size_t target_idx = 0, source_idx = source->length - 1; + target_idx < source->length; + ++target_idx, --source_idx) { + + target->data[target_idx] = source->data[source_idx]; + } +} + +void vPolyGalois256Revers(tPolyGalois256 *source) { + size_t swaps_count = source->length / 2; + size_t top = source->length - 1; + + uint8_t tmp; + + for (size_t idx = 0; idx < swaps_count; ++idx) { + tmp = source->data[idx]; + source->data[idx] = source->data[top - idx]; + source->data[top - idx] = tmp; + } +} + +void vPolyGalois256FormalDerivative(tPolyGalois256 *source, tPolyGalois256 *derivative) { + derivative->length = source->length - 1; + for (size_t idx = 0; idx < derivative->length; ++idx) { + if (idx % 2) { + derivative->data[idx] = 0; + } else { + derivative->data[idx] = source->data[idx + 1]; + } + } +} + + +uint8_t iPolyGalois256GetMax(tPolyGalois256 *source) { + uint8_t max = 0; + for (size_t idx = 0; idx < source->length; ++idx) { + if (source->data[idx] > max) { + max = source->data[idx]; + } + } + return max; +} + +uint8_t iPolyGalois256Value(tGalois256 *gf, tPolyGalois256 *env, uint8_t input) { + uint8_t value = 0; + uint8_t deg = 1; + for (size_t idx = 0; idx < env->length; ++idx) { + + uint8_t element = iGalois256Mul(gf, deg, env->data[idx]); + value = iGalois256Add(gf, value, element); + deg = iGalois256Mul(gf, deg, input); + } + return value; +} + +uint8_t iPolyGalois256IsZero(tPolyGalois256 *source) { + for (size_t idx = 0; idx < source->length; ++idx) { + if (source->data[idx] != 0) { + return 1; + } + } + return 0; +} + +void vPolyGalois256DividePolynomials( + tGalois256 *gf, + tPolyGalois256 *remainder_out, + tPolyGalois256 *divisor +) { + + size_t dividend_left = remainder_out->length - 1; + size_t divisor_left = divisor->length - 1; + + + uint8_t top_value_of_divisor = divisor->data[divisor_left]; + + int16_t remainder_left = dividend_left; + + size_t err_break = dividend_left; + do { + + for (; remainder_left >= 0; --remainder_left) { + if (remainder_out->data[remainder_left] > 0) { + break; + } + } + + if (remainder_left < divisor_left) { + return; + } + + uint8_t product_value = iGalois256Div(gf, remainder_out->data[remainder_left], top_value_of_divisor); + uint8_t product_idx = remainder_left - divisor_left; + + + for (int16_t sub_idx = divisor_left; sub_idx >= 0; --sub_idx) { + + uint8_t element = iGalois256Mul(gf, divisor->data[sub_idx], product_value); + + remainder_out->data[(product_idx + sub_idx)] = + iGalois256Sub(gf, remainder_out->data[(product_idx + sub_idx)], element); + + } + + --err_break; + } while (err_break); + + remainder_out->length = remainder_left + 1; +} + + + diff --git a/PolyGalois256.h b/PolyGalois256.h new file mode 100644 index 0000000..06fa26b --- /dev/null +++ b/PolyGalois256.h @@ -0,0 +1,48 @@ +// +// Created by zemon on 29.07.2022. +// + +#ifndef PDM_FIR_TEST_POLYGALOIS256_H +#define PDM_FIR_TEST_POLYGALOIS256_H + +#include "stdint.h" +#include "Galois256.h" +#include "stddef.h" + +//f(x) = data[0]x^0 + data[1]x^1 .... +typedef struct { + uint8_t *data; + size_t length; +} tPolyGalois256; + +size_t sPolyGalois256HighestDegree(tPolyGalois256 *poly); + +void vPolyGalois256Mul(tGalois256 *gf, tPolyGalois256 *first, tPolyGalois256 *second, tPolyGalois256 *result); + +void vPolyGalois256Copy(tPolyGalois256 *source, tPolyGalois256 *target); + +void vPolyGalois256CopyRevers(tPolyGalois256 *source, tPolyGalois256 *target); + +void vPolyGalois256Revers(tPolyGalois256 *source); + +void vPolyGalois256FormalDerivative(tPolyGalois256 *source, tPolyGalois256 *derivative); + +uint8_t iPolyGalois256GetMax(tPolyGalois256 *source); + +uint8_t iPolyGalois256Value(tGalois256 *gf, tPolyGalois256 *env, uint8_t input); + +uint8_t iPolyGalois256IsZero(tPolyGalois256 *source); + +void vPolyGalois256DividePolynomials( + tGalois256 *gf, + tPolyGalois256 *remainder_out, + tPolyGalois256 *divisor +); + +void vPolyGalois256MulNumberSelf(tGalois256 *gf, tPolyGalois256 *poly, uint8_t number); + +void vPolyGalois256Scale(tGalois256 *gf, tPolyGalois256 *orgn, uint8_t number, tPolyGalois256 *result); + +void vPolyGalois256Add(tGalois256 *gf, tPolyGalois256 *first, tPolyGalois256 *second, tPolyGalois256 *result); + +#endif //PDM_FIR_TEST_POLYGALOIS256_H diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..bab98ca --- /dev/null +++ b/modular.json @@ -0,0 +1,17 @@ +{ + "dep": [ + { + "type": "git", + "provider": "GONEC", + "repo": "Galois256" + } + ], + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "./**.c" + ] + } +} \ No newline at end of file