Line data Source code
1 : /*
2 : * libpoporon - rs.c
3 : *
4 : * This file is part of libpoporon.
5 : *
6 : * Author: Brian Armstrong (original, libcorrect)
7 : * SPDX-License-Identifier: BSD-3-Clause
8 : */
9 :
10 : #include "internal/rs.h"
11 :
12 : #include "internal/common.h"
13 : #include "internal/polynomial.h"
14 :
15 18 : static inline void rs_decoder_destroy(poporon_rs_t *rs)
16 : {
17 : uint32_t i;
18 :
19 18 : if (!rs->has_init_decode) {
20 12 : return;
21 : }
22 :
23 6 : pfree(rs->syndromes);
24 6 : pfree(rs->modified_syndromes);
25 6 : polynomial_destroy(rs->received_polynomial);
26 6 : polynomial_destroy(rs->error_locator);
27 6 : polynomial_destroy(rs->error_locator_log);
28 6 : polynomial_destroy(rs->erasure_locator);
29 6 : polynomial_destroy(rs->last_error_locator);
30 6 : polynomial_destroy(rs->error_evaluator);
31 6 : polynomial_destroy(rs->error_locator_derivative);
32 6 : pfree(rs->error_roots);
33 6 : pfree(rs->error_vals);
34 6 : pfree(rs->error_locations);
35 :
36 6 : if (rs->generator_root_exp) {
37 198 : for (i = 0; i < rs->num_roots; i++) {
38 192 : pfree(rs->generator_root_exp[i]);
39 : }
40 6 : pfree(rs->generator_root_exp);
41 : }
42 :
43 6 : if (rs->element_exp) {
44 1542 : for (i = 0; i <= rs->gf->field_size; i++) {
45 1536 : pfree(rs->element_exp[i]);
46 : }
47 6 : pfree(rs->element_exp);
48 : }
49 :
50 6 : polynomial_destroy(rs->init_from_roots_scratch[0]);
51 6 : polynomial_destroy(rs->init_from_roots_scratch[1]);
52 : }
53 :
54 19 : extern void poporon_rs_destroy(poporon_rs_t *rs)
55 : {
56 19 : if (!rs) {
57 1 : return;
58 : }
59 :
60 18 : rs_decoder_destroy(rs);
61 :
62 18 : polynomial_destroy(rs->generator);
63 18 : pfree(rs->generator_roots);
64 18 : polynomial_destroy(rs->encoded_polynomial);
65 18 : polynomial_destroy(rs->encoded_remainder);
66 :
67 18 : if (rs->gf) {
68 18 : poporon_gf_destroy(rs->gf);
69 : }
70 :
71 18 : pfree(rs);
72 : }
73 :
74 19 : extern poporon_rs_t *poporon_rs_create(uint8_t symbol_size, uint16_t primitive_polynomial, uint16_t first_consecutive_root,
75 : uint16_t primitive_element, uint8_t num_roots)
76 : {
77 : poporon_rs_t *rs;
78 : poporon_gf_t *gf;
79 : uint32_t i;
80 :
81 19 : gf = poporon_gf_create(symbol_size, primitive_polynomial);
82 19 : if (!gf) {
83 1 : return NULL;
84 : }
85 :
86 18 : rs = (poporon_rs_t *)pcalloc(1, sizeof(poporon_rs_t));
87 18 : if (!rs) {
88 0 : poporon_gf_destroy(gf);
89 0 : return NULL;
90 : }
91 :
92 18 : rs->gf = gf;
93 18 : rs->first_consecutive_root = first_consecutive_root;
94 18 : rs->generator_root_gap = primitive_element;
95 18 : rs->num_roots = num_roots;
96 18 : rs->block_length = gf->field_size;
97 18 : rs->message_length = gf->field_size - num_roots;
98 :
99 18 : rs->generator_roots = (uint16_t *)pcalloc(num_roots, sizeof(uint16_t));
100 18 : if (!rs->generator_roots) {
101 0 : poporon_rs_destroy(rs);
102 0 : return NULL;
103 : }
104 :
105 410 : for (i = 0; i < num_roots; i++) {
106 392 : rs->generator_roots[i] = gf->exp[(primitive_element * (i + first_consecutive_root)) % gf->field_size];
107 : }
108 :
109 18 : rs->generator = polynomial_create_from_roots(gf, num_roots, rs->generator_roots);
110 18 : if (!rs->generator.coeff) {
111 0 : poporon_rs_destroy(rs);
112 0 : return NULL;
113 : }
114 :
115 18 : rs->encoded_polynomial = polynomial_create(rs->block_length - 1);
116 18 : rs->encoded_remainder = polynomial_create(rs->block_length - 1);
117 18 : if (!rs->encoded_polynomial.coeff || !rs->encoded_remainder.coeff) {
118 0 : poporon_rs_destroy(rs);
119 0 : return NULL;
120 : }
121 :
122 18 : rs->has_init_decode = false;
123 :
124 18 : return rs;
125 : }
|