/* gamma = product (1-z*a^Ij) for erasure locs Ij */ void init_gamma (int gamma[]) { int e, tmp[MAXDEG]; zero_poly(gamma); zero_poly(tmp); gamma[0] = 1; for (e = 0; e < NErasures; e++) { copy_poly(tmp, gamma); scale_poly(gexp[ErasureLocs[e]], tmp); mul_z_poly(tmp); add_polys(gamma, tmp); } }
static void compute_genpoly (int nbytes, unsigned short genpoly[]) { unsigned short i, tp[256], tp1[256]; zero_poly(tp1); tp1[0] = 1; for (i = 1; i <= nbytes; i++) { zero_poly(tp); tp[0] = gexp[i]; /* set up x+a^n */ tp[1] = 1; mult_polys(genpoly, tp, tp1); copy_poly(tp1, genpoly); } }
static void compute_genpoly (int nbytes, int genpoly[]) { int i, tp[256], tp1[256]; /* multiply (x + a^n) for n = 1 to nbytes */ zero_poly(tp1); tp1[0] = 1; for (i = 1; i <= nbytes; i++) { zero_poly(tp); tp[0] = gexp[i]; /* set up x+a^n */ tp[1] = 1; mult_polys(genpoly, tp, tp1); copy_poly(tp1, genpoly); } }
/* given Psi (called Lambda in Modified_Berlekamp_Massey) and synBytes, compute the combined erasure/error evaluator polynomial as Psi*S mod z^4 */ void compute_modified_omega () { int i; int product[MAXDEG*2]; mult_polys(product, Lambda, synBytes); zero_poly(Omega); for(i = 0; i < NPAR; i++) Omega[i] = product[i]; }
// Create a generator polynomial for an n byte RS code. void init_genpoly_cache(int par) { int i; unsigned char tp[256], tp1[256]; int tmp; unsigned char *genpoly = genpoly_cache[par-1]; //multiply (x + a^n) for n = 1 to nbytes zero_poly(tp1, par*2); tp1[0] = 1; for (i = 1; i <= par; i++) { zero_poly(tp, par*2); tp[0] = gexp[i]; // set up x+a^n tp[1] = 1; mult_polys(genpoly, tp, tp1, par*2); copy_poly(tp1, genpoly, par*2); } for(i=0; i<par/2; i++) { tmp = genpoly[i] ; genpoly[i] = genpoly[par-1-i]; genpoly[par-1-i]=tmp; } for(i=0; i<256; i++) { for(int j=0; j<23; j++) genpoly_23_mult_cache[i][j] = gmult(i, genpoly_cache[22][j]); genpoly_23_mult_cache[i][23] = 0; } }
// does polynomial long division, p1 divided by p2 void divide_polys(Polynomial *p1, Polynomial *p2, Polynomial **quot, Polynomial **rem) { int max = 2 * p2->num_terms; int count = 0; Polynomial *res; Polynomial *old_temp, *new_temp; Polynomial *old_div, *new_div; Polynomial **quots; // need to allocate some polynomails, let's just assume we need // double the space of the dividend and then adjust if it goes over *quot = empty_poly(p1->num_vars, 1, p1->vars); divide_terms(&p1->terms[0], &p2->terms[0], &((*quot)->terms[0]), p1->num_vars); // not divisible from the get go, so the quot is 0 // and the remainder is all of p1 if ((*quot)->terms[0].coeff.num == 0) { *rem = copy_poly(p1); return; } // the first term was not 0, so we need to set this polynomial in our list of // partial quotients. don't forget to malloc space for the list quots = (Polynomial **) malloc(sizeof(Polynomial *) * max); quots[count] = *quot; count++; // copy the divisor old_div = copy_poly(p1); while(true) { res = multiply_polys(quots[count-1], p2); // get the new dividend new_div = subtract_polys(old_div, res); sort_polynomial(new_div); free(old_div); // see if it can be divided quots[count] = empty_poly(p1->num_vars, 1, p1->vars); divide_terms(&new_div->terms[0], &p2->terms[0], "s[count]->terms[0], p1->num_vars); if (quots[count]->terms[0].coeff.num == 0) { res = new_div; break; } // it divided, time to loop again count += 1; free(res); old_div = new_div; // increase solutions array ? if (count == max-1){ quots = double_poly_array(quots, &max); } } // sum everything in the quotes list old_temp = zero_poly(p1); for (int i = 0; i < count; i++) { new_temp = add_polys(old_temp, quots[i]); free(old_temp); free(quots[i]); old_temp = new_temp; } free(quots); // set the quotient and remainder *quot = new_temp; *rem = res; }