liberasurecode 1.8.0
Erasure Code API library
Loading...
Searching...
No Matches
isa_l_rs_vand_inv.c
Go to the documentation of this file.
1/*
2 * Copyright 2014 Kevin M Greenan
3 * Copyright 2014 Tushar Gohad
4 * Copyright 2025 Tim Burke
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * Redistributions of source code must retain the above copyright notice, this
10 * list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright notice, this
13 * list of conditions and the following disclaimer in the documentation and/or
14 * other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY
15 * THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * isa_l_rs_vand backend implementation
27 *
28 * vi: set noai tw=79 ts=4 sw=4:
29 */
30
31#include <stdlib.h>
32#include "erasurecode_backend.h"
33#include "isa_l_common.h"
34
35#define ISA_L_RS_VAND_INV_LIB_MAJOR 1
36#define ISA_L_RS_VAND_INV_LIB_MINOR 0
37#define ISA_L_RS_VAND_INV_LIB_REV 0
38#define ISA_L_RS_VAND_INV_LIB_VER_STR "1.0"
39#define ISA_L_RS_VAND_INV_LIB_NAME "isa_l_rs_vand"
40#if defined(__MACOS__) || defined(__MACOSX__) || defined(__OSX__) || defined(__APPLE__)
41#define ISA_L_RS_VAND_INV_SO_NAME "libisal" LIBERASURECODE_SO_SUFFIX ".dylib"
42#else
43#define ISA_L_RS_VAND_INV_SO_NAME "libisal" LIBERASURECODE_SO_SUFFIX ".so.2"
44#endif
45
46/* Forward declarations */
47struct ec_backend_common backend_isa_l_rs_vand_inv;
48
49static int gen_encoding_matrix(isa_l_descriptor * desc, int m, int k){
50 int i, j, ret = 1, n = m + k;
51 unsigned char p, gen = 2;
52 unsigned char *tmp = NULL;
53 unsigned char *tmp_inv_k = NULL;
54
55 /* Build a (k+m)*k Vandermonde matrix, A */
56 tmp = malloc(sizeof(char) * n * k);
57 if (tmp == NULL) {
58 goto error_free;
59 }
60 for (i = 0; i < n; i++) {
61 p = 1;
62 for (j = 0; j < k; j++) {
63 tmp[k * i + j] = p;
64 p = desc->gf_mul(p, gen);
65 }
66 gen = desc->gf_mul(gen, 2);
67 }
68
69 /* It starts with a k*k submatrix, A'; calculate inv(A') */
70 tmp_inv_k = malloc(sizeof(char) * k * k);
71 if (tmp_inv_k == NULL) {
72 goto error_free;
73 }
74 int im_ret = desc->gf_invert_matrix(tmp, tmp_inv_k, k);
75 if (im_ret < 0) {
80 goto error_free;
81 }
82
87 memset(desc->matrix, 0, k * n);
88 for (i = 0; i < k; i++)
89 desc->matrix[k * i + i] = 1;
90
91 /* Then multiply inv(A') by the rest of A for the parities */
92 for (i = k; i < n; i++) {
93 for (j = 0; j < k; j++) {
94 p = 0;
95 for (int u = 0; u < k; u++) {
96 p ^= desc->gf_mul(tmp[(i*k)+u], tmp_inv_k[(u*k)+j]);
97 }
98 desc->matrix[(i*k)+j] = p;
99 }
100 }
101 ret = 0;
102
103error_free:
104 free(tmp_inv_k);
105 free(tmp);
106 return ret;
107}
108
109static void * isa_l_rs_vand_inv_init(struct ec_backend_args *args,
110 void *backend_sohandle)
111{
112 isa_l_descriptor *desc = NULL;
113
114 desc = (isa_l_descriptor *)malloc(sizeof(isa_l_descriptor));
115 if (NULL == desc) {
116 return NULL;
117 }
118 /* Set this early so we can have a single error path */
119 desc->matrix = NULL;
120
121 desc->k = args->uargs.k;
122 desc->m = args->uargs.m;
123 if (args->uargs.w <= 0)
124 args->uargs.w = ISA_L_W;
125 desc->w = args->uargs.w;
126
127 /* validate EC arguments */
128 {
129 long long max_symbols = 1LL << desc->w;
130 if ((desc->k + desc->m) > max_symbols) {
131 goto error;
132 }
133 }
134
135 /*
136 * ISO C forbids casting a void* to a function pointer.
137 * Since dlsym return returns a void*, we use this union to
138 * "transform" the void* to a function pointer.
139 */
140 union {
141 ec_encode_data_func encodep;
142 ec_init_tables_func init_tablesp;
143 gf_gen_encoding_matrix_func gen_matrixp;
144 gf_invert_matrix_func invert_matrixp;
145 gf_mul_func gf_mulp;
146 void *vptr;
147 } func_handle = {.vptr = NULL};
148
149 /* fill in function addresses */
150 func_handle.vptr = NULL;
151 func_handle.vptr = dlsym(backend_sohandle, "ec_encode_data");
152 desc->ec_encode_data = func_handle.encodep;
153 if (NULL == desc->ec_encode_data) {
154 goto error;
155 }
156
157 func_handle.vptr = NULL;
158 func_handle.vptr = dlsym(backend_sohandle, "ec_init_tables");
159 desc->ec_init_tables = func_handle.init_tablesp;
160 if (NULL == desc->ec_init_tables) {
161 goto error;
162 }
163
164 func_handle.vptr = NULL;
165 func_handle.vptr = dlsym(backend_sohandle, "gf_invert_matrix");
166 desc->gf_invert_matrix = func_handle.invert_matrixp;
167 if (NULL == desc->gf_invert_matrix) {
168 goto error;
169 }
170
171 func_handle.vptr = NULL;
172 func_handle.vptr = dlsym(backend_sohandle, "gf_mul");
173 desc->gf_mul = func_handle.gf_mulp;
174 if (NULL == desc->gf_mul) {
175 goto error;
176 }
177
178 desc->matrix = malloc(sizeof(char) * desc->k * (desc->k + desc->m));
179 if (NULL == desc->matrix) {
180 goto error;
181 }
182
183 if (0 != gen_encoding_matrix(desc, desc->m, desc->k)) {
184 goto error;
185 }
186
190 desc->encode_tables = malloc(sizeof(unsigned char) *
191 (desc->k * desc->m * 32));
192 if (NULL == desc->encode_tables) {
193 goto error;
194 }
195
196 desc->ec_init_tables(desc->k, desc->m,
197 &desc->matrix[desc->k * desc->k],
198 desc->encode_tables);
199
200 return desc;
201
202error:
203 free(desc->matrix);
204 free(desc);
205
206 return NULL;
207}
208
209/*
210 * For the time being, we only claim compatibility with versions that
211 * match exactly
212 */
213static bool isa_l_rs_vand_inv_is_compatible_with(uint32_t version) {
214 return version == backend_isa_l_rs_vand_inv.ec_backend_version;
215}
216
217static struct ec_backend_op_stubs isa_l_rs_vand_inv_op_stubs = {
219 .EXIT = isa_l_exit,
220 .ISSYSTEMATIC = 1,
221 .ENCODE = isa_l_encode,
222 .DECODE = isa_l_decode,
223 .FRAGSNEEDED = isa_l_min_fragments,
224 .RECONSTRUCT = isa_l_reconstruct,
225 .ELEMENTSIZE = isa_l_element_size,
226 .ISCOMPATIBLEWITH = isa_l_rs_vand_inv_is_compatible_with,
227 .GETMETADATASIZE = get_backend_metadata_size_zero,
228 .GETENCODEOFFSET = get_encode_offset_zero,
229};
230
231__attribute__ ((visibility ("internal")))
232struct ec_backend_common backend_isa_l_rs_vand_inv = {
233 .id = EC_BACKEND_ISA_L_RS_VAND_INV,
238 .ec_backend_version = _VERSION(ISA_L_RS_VAND_INV_LIB_MAJOR,
241};
#define ISA_L_RS_VAND_INV_LIB_VER_STR
#define ISA_L_RS_VAND_INV_LIB_MAJOR
#define ISA_L_RS_VAND_INV_LIB_NAME
static void * isa_l_rs_vand_inv_init(struct ec_backend_args *args, void *backend_sohandle)
static bool isa_l_rs_vand_inv_is_compatible_with(uint32_t version)
#define ISA_L_RS_VAND_INV_LIB_REV
struct ec_backend_common backend_isa_l_rs_vand_inv
#define ISA_L_RS_VAND_INV_LIB_MINOR
__attribute__((visibility("internal")))
static struct ec_backend_op_stubs isa_l_rs_vand_inv_op_stubs
static int gen_encoding_matrix(isa_l_descriptor *desc, int m, int k)
#define ISA_L_RS_VAND_INV_SO_NAME