Line data Source code
1 : /*
2 : * libpoporon - gf.c
3 : *
4 : * Copyright (c) 2025 Go Kudo
5 : *
6 : * This library is licensed under the BSD 3-Clause License.
7 : * For license details, please refer to the LICENSE file.
8 : *
9 : * SPDX-FileCopyrightText: Go Kudo <zeriyoshi@gmail.com>
10 : * SPDX-License-Identifier: BSD-3-Clause
11 : */
12 :
13 : #include "poporon_internal.h"
14 :
15 16 : extern void poporon_gf_destroy(poporon_gf_t *gf)
16 : {
17 16 : if (!gf) {
18 1 : return;
19 : }
20 :
21 15 : if (gf->exp2log) {
22 15 : pfree(gf->exp2log);
23 : }
24 :
25 15 : if (gf->log2exp) {
26 15 : pfree(gf->log2exp);
27 : }
28 :
29 15 : pfree(gf);
30 : }
31 :
32 19 : extern poporon_gf_t *poporon_gf_create(uint8_t symbol_size, uint16_t generator_polynomial)
33 : {
34 : poporon_gf_t *gf;
35 : uint16_t field_element;
36 : uint8_t i;
37 :
38 19 : if (symbol_size < 1 || symbol_size > 16) {
39 4 : return NULL;
40 : }
41 :
42 15 : gf = (poporon_gf_t *)pmalloc(sizeof(poporon_gf_t));
43 15 : if (!gf) {
44 : return NULL; /* LCOV_EXCL_LINE */
45 : }
46 :
47 15 : gf->symbol_size = symbol_size;
48 15 : gf->field_size = (1 << symbol_size) - 1;
49 15 : gf->generator_polynomial = generator_polynomial;
50 :
51 15 : gf->log2exp = (uint16_t *)pmalloc((gf->field_size + 1) * sizeof(uint16_t));
52 15 : if (!gf->log2exp) {
53 : /* LCOV_EXCL_START */
54 : poporon_gf_destroy(gf);
55 : return NULL;
56 : /* LCOV_EXCL_STOP */
57 : }
58 :
59 15 : gf->exp2log = (uint16_t *)pmalloc((gf->field_size + 1) * sizeof(uint16_t));
60 15 : if (!gf->exp2log) {
61 : /* LCOV_EXCL_START */
62 : poporon_gf_destroy(gf);
63 : return NULL;
64 : /* LCOV_EXCL_STOP */
65 : }
66 :
67 15 : gf->exp2log[0] = gf->field_size; /* log(0) = -inf represented as field_size */
68 15 : gf->log2exp[gf->field_size] = 0; /* exp(-inf) = 0 */
69 :
70 15 : field_element = 1;
71 3360 : for (i = 0; i < gf->field_size; i++) {
72 3345 : gf->exp2log[field_element] = i;
73 3345 : gf->log2exp[i] = field_element;
74 :
75 3345 : field_element <<= 1;
76 :
77 3345 : if (field_element & (1 << symbol_size)) {
78 1680 : field_element ^= generator_polynomial;
79 : }
80 :
81 3345 : field_element &= gf->field_size;
82 : }
83 :
84 15 : if (field_element != gf->log2exp[0]) {
85 : /* LCOV_EXCL_START */
86 : poporon_gf_destroy(gf);
87 :
88 : return NULL;
89 : /* LCOV_EXCL_STOP */
90 : }
91 :
92 15 : return gf;
93 : }
94 :
95 259 : uint8_t poporon_gf_mod(poporon_gf_t *gf, uint16_t value)
96 : {
97 259 : return gf_mod(gf, value);
98 : }
|