GFn_el_t & GFn_el_t::operator /= (unsigned int _a) { unsigned int a = gf_inv(prime, _a%prime); poly_mul(prime, degree, comp, degree, comp, 0, &a); return *this; }
gf gf_div(gf a, gf b) { gf c = gf_inv(b); gf result = gf_mul(a, c); return result; }
MAT key_genmat(gf_t *L, poly_t g) { //L- Support //t- Number of errors, i.e.=30. //n- Length of the Goppa code, i.e.=2^11 //m- The extension degree of the GF, i.e. =11 //g- The generator polynomial. gf_t x,y; MAT H,R; int i,j,k,r,n; int * perm, Laux[LENGTH]; n=LENGTH;//2^11=2048 r=NB_ERRORS*gf_extd();//32 x 11=352 H=mat_ini(r,n);//initialize matrix with actual no. of bits. mat_set_to_zero(H); //set the matrix with all 0's. for(i=0;i< n;i++) { x = poly_eval(g,L[i]);//evaluate the polynomial at the point L[i]. x = gf_inv(x); y = x; for(j=0;j<NB_ERRORS;j++) { for(k=0;k<gf_extd();k++) { if(y & (1<<k))//if((y>>k) & 1) mat_set_coeff_to_one(H,j*gf_extd()+k,i);//the co-eff. are set in 2^0,...,2^11 ; 2^0,...,2^11 format along the rows/cols? } y = gf_mul(y,L[i]); } }//The H matrix is fed. perm = mat_rref(H); if (perm == NULL) { mat_free(H); return NULL; } R = mat_ini(n-r,r); mat_set_to_zero(R); //set the matrix with all 0's. for (i = 0; i < R->rown; ++i) for (j = 0; j < R->coln; ++j) if (mat_coeff(H,j,perm[i])) mat_change_coeff(R,i,j); for (i = 0; i < LENGTH; ++i) Laux[i] = L[perm[i]]; for (i = 0; i < LENGTH; ++i) L[i] = Laux[i]; mat_free(H); free(perm); return (R); }
int gf_invert_matrix(unsigned char *in_mat, unsigned char *out_mat, const int n) { int i, j, k; unsigned char temp; // Set out_mat[] to the identity matrix for (i = 0; i < n * n; i++) // memset(out_mat, 0, n*n) out_mat[i] = 0; for (i = 0; i < n; i++) out_mat[i * n + i] = 1; // Inverse for (i = 0; i < n; i++) { // Check for 0 in pivot element if (in_mat[i * n + i] == 0) { // Find a row with non-zero in current column and swap for (j = i + 1; j < n; j++) if (in_mat[j * n + i]) break; if (j == n) // Couldn't find means it's singular return -1; for (k = 0; k < n; k++) { // Swap rows i,j temp = in_mat[i * n + k]; in_mat[i * n + k] = in_mat[j * n + k]; in_mat[j * n + k] = temp; temp = out_mat[i * n + k]; out_mat[i * n + k] = out_mat[j * n + k]; out_mat[j * n + k] = temp; } } temp = gf_inv(in_mat[i * n + i]); // 1/pivot for (j = 0; j < n; j++) { // Scale row i by 1/pivot in_mat[i * n + j] = gf_mul(in_mat[i * n + j], temp); out_mat[i * n + j] = gf_mul(out_mat[i * n + j], temp); } for (j = 0; j < n; j++) { if (j == i) continue; temp = in_mat[j * n + i]; for (k = 0; k < n; k++) { out_mat[j * n + k] ^= gf_mul(temp, out_mat[i * n + k]); in_mat[j * n + k] ^= gf_mul(temp, in_mat[i * n + k]); } } } return 0; }
void gf_gen_cauchy1_matrix(unsigned char *a, int m, int k) { int i, j; unsigned char *p; // Identity matrix in high position memset(a, 0, k * m); for (i = 0; i < k; i++) a[k * i + i] = 1; // For the rest choose 1/(i + j) | i != j p = &a[k * k]; for (i = k; i < m; i++) for (j = 0; j < k; j++) *p++ = gf_inv(i ^ j); }
// p contiendra son reste modulo g void poly_rem(poly_t p, poly_t g) { int i, j, d; gf_t a, b; d = poly_deg(p) - poly_deg(g); if (d >= 0) { a = gf_inv(poly_tete(g)); for (i = poly_deg(p); d >= 0; --i, --d) { if (poly_coeff(p, i) != gf_zero()) { b = gf_mul_fast(a, poly_coeff(p, i)); for (j = 0; j < poly_deg(g); ++j) poly_addto_coeff(p, j + d, gf_mul_fast(b, poly_coeff(g, j))); poly_set_coeff(p, i, gf_zero()); } } poly_set_deg(p, poly_deg(g) - 1); while ((poly_deg(p) >= 0) && (poly_coeff(p, poly_deg(p)) == gf_zero())) poly_set_deg(p, poly_deg(p) - 1); } }
int main(void) { int i, p, x; uint8_t s1[256], s1_inv[256], s2[256], s2_inv[256]; for (x=0; x<256; x++) { // generate s-box 1 s1[x] = matmul8(A, gf_inv(x)) ^ 0x63; // generate s-box 2 s2[x] = matmul8(B, gf_exp(x, 247, 0x1b)) ^ 0xE2; } for (i=0; i<256; i++) { s1_inv[s1[i]] = i; s2_inv[s2[i]] = i; } bin2hex("ARIA s1", s1, 256); bin2hex("ARIA inverse s1", s1_inv, 256); bin2hex("ARIA s2", s2, 256); bin2hex("ARIA inverse s2", s2_inv, 256); return 0; }
poly_t poly_quo(poly_t p, poly_t d) { int i, j, dd, dp; gf_t a, b; poly_t quo, rem; dd = poly_calcule_deg(d); dp = poly_calcule_deg(p); rem = poly_copy(p); quo = poly_alloc(dp - dd); poly_set_deg(quo, dp - dd); a = gf_inv(poly_coeff(d, dd)); for (i = dp; i >= dd; --i) { b = gf_mul_fast(a, poly_coeff(rem, i)); poly_set_coeff(quo, i - dd, b); if (b != gf_zero()) { poly_set_coeff(rem, i, gf_zero()); for (j = i - 1; j >= i - dd; --j) poly_addto_coeff(rem, j, gf_mul_fast(b, poly_coeff(d, dd - i + j))); } } poly_free(rem); return quo; }
const GFn_el_t GFn_el_t::inv() const { int i; unsigned int u0[degree + 1], r0[degree + 1]; unsigned int u1[degree + 1], r1[degree + 1]; unsigned int q[degree + 1], r[degree + 1]; unsigned int u[2*degree + 1]; { for(i = degree; i >= 0 && 0 == comp[i]; --i) r1[i] = 0; assert( i >= 0 ); if( 0 == i ) return GFn_el_t(GFn, gf_inv(prime, comp[0])); for(; i >= 0; --i) r1[i] = comp[i]; for(i = degree; i >= 1; --i) u1[i] = 0; u1[0] = 1; } { poly_divmod(prime, degree, u0, degree, r0, GFn.degree, GFn.mod, degree, comp); poly_sub(prime, degree, u0, -1, NULL, degree, u0); } while( true ) { { for(i = degree; i >= 0 && 0 == r0[i] ; --i); assert( i >= 0 ); if( 0 == i ) { unsigned int inv = gf_inv(prime, r0[0]); poly_mul(prime, degree, u0, degree, u0, 0, &inv); return GFn_el_t(GFn, u0); } } poly_divmod(prime, degree, q, degree, r, degree, r1, degree, r0); for(i = degree; i >= 0; --i) { r1[i] = r0[i]; r0[i] = r[i]; } poly_mul(prime, 2*degree, u, degree, u0, degree, q); poly_sub(prime, 2*degree, u, degree, u1, 2*degree, u); for( i = degree; i >= 0; --i) u1[i] = u0[i]; poly_divmod(prime, -1, NULL, degree, u0, 2*degree, u, GFn.degree, GFn.mod); } }