Gf.h
#ifndef GF_H #define GF_H
typedef unsigned short gf_t;
int gf_extension_degree, gf_cardinality, gf_multiplicative_order; gf_t * gf_log;
gf_t * gf_exp;
/* MACROs for certain operations */ #define gf_extd() gf_extension_degree #define gf_card() gf_cardinality
#define gf_ord() gf_multiplicative_order #define gf_unit() 1
#define gf_zero() 0
#define gf_add(x, y) ((x) ^ (y))
#define gf_exp(i) gf_exp[i] /* alpha^i */
#define gf_log(x) gf_log[x] /* return i when x=alpha^i */ // residual modulo q-1
// when -q < d < 0, we get (q-1+d) // when 0 <= d < q, we get (d)
// when q <= d < 2q-1, we get (d-q+1)
#define _gf_modq_1(d) (((d) & gf_ord()) + ((d) >> gf_extd()))
/* we obtain a value between 0 and (q-1) included, the class of 0 is
represented by 0 or q-1 (this is why we write _K->exp[q-1]=_K->exp[0]=1)*/ #define gf_mul_fast(x, y) ((y) ? gf_exp[_gf_modq_1(gf_log[x] + gf_log[y])] : 0) #define gf_mul(x, y) ((x) ? gf_mul_fast(x, y) : 0)
#define gf_square(x) ((x) ? gf_exp[_gf_modq_1(gf_log[x] << 1)] : 0)
#define gf_sqrt(x) ((x) ? gf_exp[_gf_modq_1(gf_log[x] << (gf_extd()-1))] : 0) // Try to devide by zero and get what you deserve!
#define gf_div(x, y) ((x) ? gf_exp[_gf_modq_1(gf_log[x] - gf_log[y])] : 0) #define gf_inv(x) gf_exp[gf_ord() - gf_log[x]]
/****** gf.c ******/ int gf_init(int extdeg); gf_t gf_rand(int (*u8rnd)()); gf_t gf_pow(gf_t x, int i); #endif /* GF_H */
GF.C
#include <stdio.h> #include <stdlib.h> #include "gf.h"
#define MAX_EXT_DEG 16//this is our primary consideration....think about changing!? static unsigned prim_poly[MAX_EXT_DEG + 1] = {
03, /* extension degree 1 (!) never used */ 07, /* extension degree 2 */ 013, /* extension degree 3 */ 023, /* extension degree 4 */ 045, /* extension degree 5 */ 0103, /* extension degree 6 */ 0203, /* extension degree 7 */ 0435, /* extension degree 8 */ 01041, /* extension degree 9 */ 02011, /* extension degree 10 */ 04005, /* extension degree 11 */ 010123, /* extension degree 12 */ 020033, /* extension degree 13 */ 042103, /* extension degree 14 */ 0100003, /* extension degree 15 */ 0210013 /* extension degree 16 */ };//we predefine the primitive polynomials here. / *********************************************************************************** **********/ ////////////////////////////////////GF Functions.////////////////////////////////////////////// / *********************************************************************************** **********/
// construct the table gf_exp[i]=alpha^i void gf_init_exp() {
int i;
gf_exp = (gf_t *) malloc((1 << gf_extd()) * sizeof (gf_t)); gf_exp[0] = 1;
for (i = 1; i < gf_ord(); ++i) { gf_exp[i] = gf_exp[i - 1] << 1;
if (gf_exp[i - 1] & (1 << (gf_extd()-1))) gf_exp[i] ^= prim_poly[gf_extd()]; }
// hack for the multiplication gf_exp[gf_ord()] = 1;
}
// construct the table gf_log[alpha^i]=i void gf_init_log()
{
int i;
gf_log = (gf_t *) malloc((1 << gf_extd()) * sizeof (gf_t)); gf_log[0] = gf_ord();//(1 << 16) - 1; // log of 0 par convention for (i = 0; i < gf_ord() ; ++i)
gf_log[gf_exp[i]] = i; }
int init_done = 0; int gf_init(int extdeg)
{
if (extdeg > MAX_EXT_DEG) {
fprintf(stderr,"Extension degree %d not implemented !\n", extdeg); exit(0); } if (init_done != extdeg) { if (init_done) { free(gf_exp); free(gf_log); }
init_done = gf_extension_degree = extdeg; gf_cardinality = 1 << extdeg; gf_multiplicative_order = gf_cardinality - 1; gf_init_exp(); gf_init_log(); } return 1; }
// we suppose i >= 0. Par convention 0^0 = 1 gf_t gf_pow(gf_t x, int i) { if (i == 0) return 1; else if (x == 0) return 0; else { // i mod (q-1) while (i >> gf_extd())
i = (i & (gf_ord())) + (i >> gf_extd()); i *= gf_log[x];
while (i >> gf_extd())
i = (i & (gf_ord())) + (i >> gf_extd()); return gf_exp[i];
} }
// u8rnd is a function returning a random byte gf_t gf_rand(int (*u8rnd)()) {
return (u8rnd() ^ (u8rnd() << 8)) & gf_ord(); }
POLY.H
#ifndef POLY_H #define POLY_H #include "gf.h"
typedef struct polynome { int deg, size;
gf_t * coeff;
} * poly_t; /* polynomial has coefficients in the finite field */ #ifndef TRUE
#define TRUE 1 #define FALSE 0 #endif
#define poly_size(p) ((p)->size)
#define poly_set_deg(p, d) ((p)->deg = (d)) #define poly_coeff(p, i) ((p)->coeff[i])
#define poly_set_coeff(p, i, a) ((p)->coeff[i] = (a))
#define poly_addto_coeff(p, i, a) ((p)->coeff[i] = gf_add((p)->coeff[i], (a))) #define poly_multo_coeff(p, i, a) ((p)->coeff[i] = gf_mul((p)->coeff[i], (a))) #define poly_tete(p) ((p)->coeff[(p)->deg])
/****** poly.c ******/
int poly_calcule_deg(poly_t p); poly_t poly_alloc(int d);
poly_t poly_alloc_from_string(int d, const unsigned char * s); poly_t poly_copy(poly_t p);
void poly_free(poly_t p);
void poly_set_to_zero(poly_t p); void poly_set(poly_t p, poly_t q); poly_t poly_mul(poly_t p, poly_t q); void poly_rem(poly_t p, poly_t g);
void poly_sqmod_init(poly_t g, poly_t * sq);
void poly_sqmod(poly_t res, poly_t p, poly_t * sq, int d); poly_t poly_gcd(poly_t p1, poly_t p2);
poly_t poly_quo(poly_t p, poly_t d); gf_t poly_eval(poly_t p, gf_t a); int poly_degppf(poly_t g);
void poly_eeaux(poly_t * u, poly_t * v, poly_t p, poly_t g, int t); poly_t * poly_syndrome_init(poly_t generator, gf_t *support, int n); poly_t * poly_sqrtmod_init(poly_t g);
poly_t poly_randgen_irred(int t, int (*u8rnd)()); #endif /* POLY_H */
POLY.C
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "gf.h" #include "poly.h" / *********************************************************************************** **********/ ////////////////////////////////////POLYNOMIAL Functions/////////////////////////////////////// / *********************************************************************************** **********/ poly_t poly_alloc(int d) { poly_t p;p = (poly_t) malloc(sizeof (struct polynome)); p->deg = -1;
p->size = d + 1;
p->coeff = (gf_t *) calloc(p->size, sizeof (gf_t)); return p;
// assumes s has the proper allocated size
poly_t poly_alloc_from_string(int d, const unsigned char * s) { poly_t p;
p = (poly_t) malloc(sizeof (struct polynome)); p->deg = -1; p->size = d + 1; p->coeff = (gf_t *) s; return p; } poly_t poly_copy(poly_t p) { poly_t q;
q = (poly_t) malloc(sizeof (struct polynome)); q->deg = p->deg;
q->size = p->size;
q->coeff = (gf_t *) calloc(q->size, sizeof (gf_t)); memcpy(q->coeff, p->coeff, p->size * sizeof (gf_t)); return q; } void poly_free(poly_t p) { free(p->coeff); free(p); } void poly_set_to_zero(poly_t p) {
memset(p->coeff, 0, p->size * sizeof (gf_t)); p->deg = -1;
}
int poly_calcule_deg(poly_t p) { int d = p->size - 1;
while ((d >= 0) && (p->coeff[d] == gf_zero())) --d;
p->deg = d; return d; }
// copy q in p
void poly_set(poly_t p, poly_t q) { int d = p->size - q->size;
if (d < 0) {
memcpy(p->coeff, q->coeff, p->size * sizeof (gf_t)); poly_calcule_deg(p);
} else {
memcpy(p->coeff, q->coeff, q->size * sizeof (gf_t)); memset(p->coeff + q->size, 0, d * sizeof (gf_t)); p->deg = q->deg;
} }
gf_t poly_eval_aux(gf_t * coeff, gf_t a, int d) { gf_t b;
for (; d >= 0; --d) if (b != gf_zero())
b = gf_add(gf_mul(b, a), coeff[d]); else
b = coeff[d]; return b;
}
poly_t poly_mul(poly_t p, poly_t q) { int i,j,dp,dq; poly_t r; poly_calcule_deg(p); poly_calcule_deg(q); dp = poly_deg(p); dq = poly_deg(q); r=poly_alloc(dp+dq); for (i = 0; i <= dp; ++i) for (j = 0; j <= dq; ++j) poly_addto_coeff(r,i+j,gf_mul(poly_coeff(p,i),poly_coeff(q,j))); poly_calcule_deg(r); return(r); } gf_t poly_eval(poly_t p, gf_t a) {
return poly_eval_aux(p->coeff, a, poly_deg(p)); }
// p contain it's remainder 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);
} }
void poly_sqmod_init(poly_t g, poly_t * sq) { int i, d;
d = poly_deg(g);
for (i = 0; i < d / 2; ++i) { // sq[i] = x^(2i) mod g = x^(2i) poly_set_to_zero(sq[i]);
poly_set_deg(sq[i], 2 * i);
poly_set_coeff(sq[i], 2 * i, gf_unit()); }
for (; i < d; ++i) {
// sq[i] = x^(2i) mod g = (x^2 * sq[i-1]) mod g memset(sq[i]->coeff, 0, 2 * sizeof (gf_t));
memcpy(sq[i]->coeff + 2, sq[i - 1]->coeff, d * sizeof (gf_t)); poly_set_deg(sq[i], poly_deg(sq[i - 1]) + 2);
poly_rem(sq[i], g); }
}
/*Modulo p square of a certain polynomial g, sq[] contains the square Modulo g of the base canonical polynomials of degree < d, where d is the degree of G. The table sq[] will be calculated by poly_sqmod_init*/ void poly_sqmod(poly_t res, poly_t p, poly_t * sq, int d) {
int i, j; gf_t a;
poly_set_to_zero(res); // terms of low degree for (i = 0; i < d / 2; ++i)
poly_set_coeff(res, i * 2, gf_square(poly_coeff(p, i))); // terms of high degree
for (; i < d; ++i) {
if (poly_coeff(p, i) != gf_zero()) { a = gf_square(poly_coeff(p, i)); for (j = 0; j < d; ++j)
poly_addto_coeff(res, j, gf_mul_fast(a, poly_coeff(sq[i], j))); }
}
// Update degre
poly_set_deg(res, d - 1);
while ((poly_deg(res) >= 0) && (poly_coeff(res, poly_deg(res)) == gf_zero())) poly_set_deg(res, poly_deg(res) - 1);
}
// destructive
poly_t poly_gcd_aux(poly_t p1, poly_t p2) { if (poly_deg(p2) == -1) return p1; else { poly_rem(p1, p2); return poly_gcd_aux(p2, p1); } }
poly_t poly_gcd(poly_t p1, poly_t p2) { poly_t a, b, c;
a = poly_copy(p1); b = poly_copy(p2);
if (poly_deg(a) < poly_deg(b))
else c = poly_copy(poly_gcd_aux(a, b)); poly_free(a); poly_free(b); return c; }
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; }
// Returns the degree of the smallest factor int poly_degppf(poly_t g) {
int i, d, res; poly_t *u, p, r, s; d = poly_deg(g);
u = malloc(d * sizeof (poly_t *)); for (i = 0; i < d; ++i) u[i] = poly_alloc(d + 1); poly_sqmod_init(g, u); p = poly_alloc(d - 1); poly_set_deg(p, 1); poly_set_coeff(p, 1, gf_unit()); r = poly_alloc(d - 1); res = d;
for (i = 1; i <= (d / 2) * gf_extd(); ++i) { poly_sqmod(r, p, u, d);
// r = x^(2^i) mod g
if ((i % gf_extd()) == 0) { // so 2^i = (2^m)^j (m ext. degree) poly_addto_coeff(r, 1, gf_unit());
poly_calcule_deg(r); // The degree may change s = poly_gcd(g, r);
if (poly_deg(s) > 0) { poly_free(s);
res = i / gf_extd(); break;
}
poly_free(s);
poly_addto_coeff(r, 1, gf_unit());
poly_calcule_deg(r); // The degree may change }
// No need for the exchange s s = p; p = r; r = s; } poly_free(p); poly_free(r); for (i = 0; i < d; ++i) { poly_free(u[i]); } free(u); return res; }
// We suppose deg(g) >= deg(p)
void poly_eeaux(poly_t * u, poly_t * v, poly_t p, poly_t g, int t) { int i, j, dr, du, delta;
gf_t a;
poly_t aux, r0, r1, u0, u1;
// initialisation of the local variables // r0 <- g, r1 <- p, u0 <- 0, u1 <- 1 dr = poly_deg(g); r0 = poly_alloc(dr); r1 = poly_alloc(dr - 1); u0 = poly_alloc(dr - 1); u1 = poly_alloc(dr - 1); poly_set(r0, g); poly_set(r1, p); poly_set_to_zero(u0); poly_set_to_zero(u1); poly_set_coeff(u1, 0, gf_unit()); poly_set_deg(u1, 0); // invariants: // r1 = u1 * p + v1 * g // r0 = u0 * p + v0 * g
// and deg(u1) = deg(g) - deg(r0)
// It stops when deg (r1) <t (deg (r0)> = t)
// And therefore deg (u1) = deg (g) - deg (r0) <deg (g) - t du = 0; dr = poly_deg(r1); delta = poly_deg(r0) - dr; while (dr >= t) { for (j = delta; j >= 0; --j) { a = gf_div(poly_coeff(r0, dr + j), poly_coeff(r1, dr)); if (a != gf_zero()) {
// u0(z) <- u0(z) + a * u1(z) * z^j for (i = 0; i <= du; ++i){
}
// r0(z) <- r0(z) + a * r1(z) * z^j for (i = 0; i <= dr; ++i)
poly_addto_coeff(r0, i + j, gf_mul_fast(a, poly_coeff(r1, i))); }
}
// exchange
aux = r0; r0 = r1; r1 = aux; aux = u0; u0 = u1; u1 = aux; du = du + delta;
delta = 1;
while (poly_coeff(r1, dr - delta) == gf_zero()) delta++; dr -= delta; } poly_set_deg(u1, du); poly_set_deg(r1, dr); //return u1 and r1; *u=u1; *v=r1; poly_free(r0); poly_free(u0); }
// The field is already defined
// Return a polynomial of degree t irreducible in the field poly_t poly_randgen_irred(int t, int (*u8rnd)()) {
int i; poly_t g; g = poly_alloc(t); poly_set_deg(g, t); poly_set_coeff(g, t, gf_unit()); i = 0; do for (i = 0; i < t; ++i) poly_set_coeff(g, i, gf_rand(u8rnd)); while (poly_degppf(g) < t); return g; } // p = p * x mod g // p of degree <= deg(g)-1
void poly_shiftmod(poly_t p, poly_t g) { int i, t;
gf_t a;
t = poly_deg(g);
a = gf_div(p->coeff[t-1], g->coeff[t]); for (i = t - 1; i > 0; --i)
p->coeff[i] = gf_add(p->coeff[i - 1], gf_mul(a, g->coeff[i])); p->coeff[0] = gf_mul(a, g->coeff[0]);
poly_t * poly_sqrtmod_init(poly_t g) { int i, t;
poly_t * sqrt, aux, p, q, * sq_aux; t = poly_deg(g);
sq_aux = malloc(t * sizeof (poly_t)); for (i = 0; i < t; ++i) sq_aux[i] = poly_alloc(t + 1); poly_sqmod_init(g, sq_aux); q = poly_alloc(t - 1); p = poly_alloc(t - 1); poly_set_deg(p, 1); poly_set_coeff(p, 1, gf_unit()); // q(z) = 0, p(z) = z
for (i = 0; i < t * gf_extd() - 1; ++i) { // q(z) <- p(z)^2 mod g(z) poly_sqmod(q, p, sq_aux, t); // q(z) <-> p(z) aux = q; q = p; p = aux; } // p(z) = z^(2^(tm-1)) mod g(z) = sqrt(z) mod g(z) sqrt = malloc(t * sizeof (poly_t));
for (i = 0; i < t; ++i) sqrt[i] = poly_alloc(t - 1); poly_set(sqrt[1], p); poly_calcule_deg(sqrt[1]); for(i = 3; i < t; i += 2) { poly_set(sqrt[i], sqrt[i - 2]); poly_shiftmod(sqrt[i], g); poly_calcule_deg(sqrt[i]); } for (i = 0; i < t; i += 2) { poly_set_to_zero(sqrt[i]); sqrt[i]->coeff[i / 2] = gf_unit(); sqrt[i]->deg = i / 2; } for (i = 0; i < t; ++i) poly_free(sq_aux[i]); free(sq_aux); poly_free(p); poly_free(q); return sqrt; }
poly_t * poly_syndrome_init(poly_t generator, gf_t *support, int n) {
int i,j,t; gf_t a; poly_t * F;
F = malloc(n * sizeof (poly_t)); t = poly_deg(generator); //g(z)=g_t+g_(t-1).z^(t-1)+...+g_1.z+g_0 //f(z)=f_(t-1).z^(t-1)+...+f_1.z+f_0 for(j=0;j<n;j++) { F[j] = poly_alloc(t-1); poly_set_coeff(F[j],t-1,gf_unit()); for(i=t-2;i>=0;i--) { poly_set_coeff(F[j],i,gf_add(poly_coeff(generator,i+1), gf_mul(support[j],poly_coeff(F[j],i+1)))); } a = gf_add(poly_coeff(generator,0),gf_mul(support[j],poly_coeff(F[j],0))); for(i=0;i<t;i++) { poly_set_coeff(F[j],i, gf_div(poly_coeff(F[j],i),a)); } } return F; }
MAT.H
#ifndef _MATRIX_H #define _MATRIX_H#define BITS_PER_LONG (8 * sizeof (unsigned long)) typedef struct matrix{
int rown;//number of rows. int coln;//number of columns.
int rwdcnt;//number of words in a row int alloc_size;//number of allocated bytes unsigned long *elem;//row index.
}*binmat_t;
#define mat_coeff(A, i, j) (((A)->elem[(i) * A->rwdcnt + (j) / BITS_PER_LONG] >> (j % BITS_PER_LONG)) & 1)
//#define mat_row(A, i) ((A)->elem + ((i) * A->rwdcnt))
#define mat_set_coeff_to_one(A, i, j) ((A)->elem[(i) * A->rwdcnt + (j) / BITS_PER_LONG] |= (1UL << ((j) % BITS_PER_LONG)))
#define mat_change_coeff(A, i, j) ((A)->elem[(i) * A->rwdcnt + (j) / BITS_PER_LONG] ^= (1UL << ((j) % BITS_PER_LONG)))
#define mat_set_to_zero(R) memset((R)->elem,0,(R)->alloc_size); binmat_t mat_ini(int rown, int coln);
binmat_t mat_ini_from_string(int rown, int coln, const unsigned char * s); void mat_free(binmat_t A);
binmat_t mat_copy(binmat_t A);
binmat_t mat_rowxor(binmat_t A,int a, int b); int * mat_rref(binmat_t A);
void mat_vec_mul(unsigned long *cR, unsigned char *x, binmat_t A); binmat_t mat_mul(binmat_t A, binmat_t B);
MAT.C
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "matrix.h" / *********************************************************************************** **********/ ////////////////////////////////////MATRIX Functions/////////////////////////////////////////// / *********************************************************************************** **********///take a look at the MSB-LSB format??? binmat_t mat_ini (int rown, int coln) {
binmat_t A;
A = (binmat_t) malloc (sizeof (struct matrix)); A->coln = coln;
A->rown = rown;
A->rwdcnt = (1 + (coln - 1) / BITS_PER_LONG);
A->alloc_size = rown * A->rwdcnt * sizeof (unsigned long); A->elem = (unsigned long *)malloc(A->alloc_size);
return A; }
// assumes s has the proper allocated size
binmat_t mat_ini_from_string(int rown, int coln, const unsigned char * s) {
binmat_t A;
A = (binmat_t) malloc (sizeof (struct matrix)); A->coln = coln;
A->rown = rown;
A->rwdcnt = (1 + (coln - 1) / BITS_PER_LONG);
A->alloc_size = rown * A->rwdcnt * sizeof (unsigned long); A->elem = (unsigned long *) s;
return A; } void mat_free(binmat_t A) { free(A->elem); free(A); }
binmat_t mat_copy(binmat_t A)//copying matrix (for the form [G|I]...) {
binmat_t X; int i;
X=mat_ini(A->rown,A->coln);//initialize the matrix. for(i=0;i<((A->rwdcnt)*(A->rown));i++)
X->elem[i]=A->elem[i]; return(X);
}
binmat_t mat_rowxor(binmat_t A,int a, int b) { int i; for(i=0;i<A->rwdcnt;i++) { A->elem[a*A->rwdcnt+i]^=A->elem[b*A->rwdcnt+i]; } return A; }
//the matrix is reduced from LSB...(from right) int * mat_rref(binmat_t A)
{
int i,j,failcnt,findrow,max=A->coln - 1; int *perm;
perm = malloc(A->coln * sizeof(int)); for(i=0;i<A->coln;i++) perm[i]=i;//initialize permutation. failcnt = 0; for(i=0;i<A->rown;i++,max--) { findrow=0; for(j=i;j<A->rown;j++) { if(mat_coeff(A,j,max))//(A->elem[(j*A->coln)+max]) { //max--;
if (i!=j)//not needed as ith row is 0 and jth row is 1. A=mat_rowxor(A,i,j);//xor to the row.(swap)?
findrow=1; break;
}//largest value found (end if)
// break;
}
if(!findrow)//if no row with a 1 found then swap last column and the column with no 1 down.
{
perm[A->coln - A->rown - 1 - failcnt] = max; failcnt++; if (!max) { return NULL; } i--; } else
{
perm[i+A->coln - A->rown] = max;
for(j=i+1;j<A->rown;j++)//fill the column downwards with 0's {
if(mat_coeff(A,j,(max)))//(A->elem[j*A->coln+max+1]) A=mat_rowxor(A,j,i);//check the arg. order.
}
for(j=i-1;j>=0;j--)//fill the column with 0's upwards too. { if(mat_coeff(A,j,(max)))//(A->elem[j*A->coln+max+1]) A=mat_rowxor(A,j,i); } } }//end for(i) return(perm); }
void mat_vec_mul(unsigned long *cR, unsigned char *x, binmat_t A) {
int i,j;
unsigned long *pt;
memset(cR,0,A->rwdcnt*sizeof(long)); pt = A->elem;
for(i=0;i<A->rown;i++)//extract the first column in the form of char array. { if((x[i/8]>>(i%8))&1) for (j = 0; j < A->rwdcnt; ++j) cR[j] ^= *pt++; else pt += A->rwdcnt; } }
binmat_t mat_mul(binmat_t A, binmat_t B) { binmat_t C; int i,j,k; if (A->coln != B->rown) exit(0); C = mat_ini(A->rown, B->coln); memset(C->elem,0,C->alloc_size); for(i=0;i<A->rown;i++) for(j=0;j<B->coln;j++) for (k = 0; k < A->coln; ++k)
if (mat_coeff(A,i,k) && mat_coeff(B,k,j)) mat_change_coeff(C,i,j);
return C; }
Key pair
#include <string.h> #include "sizes.h" #include "gf.h" #include "poly.h" #include "matrix.h"
__inline int u8rnd() { return random() & 0xff; }
__inline unsigned int u32rnd() { return u8rnd() ^ (u8rnd()<<8) ^ (u8rnd()<<16) ^ (u8rnd()<<24); } / *********************************************************************************** **********/ ////////////////////////////////////KEY-GENERATION Function//////////////////////////////////// / *********************************************************************************** **********/
//The support for key-gen void gop_supr(int n,gf_t *L) { unsigned int i, j; gf_t tmp; for (i = 0; i < n; ++i) { j = i + u32rnd() % (n - i); tmp = L[j]; L[j] = L[i]; L[i] = tmp; } }
binmat_t 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; binmat_t H,R; int i,j,k,r,n;
int * perm, Laux[LENGTH]; n=LENGTH;//2^11=2048
r=NB_ERRORS*EXT_DEGREE;//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 = gf_inv(x); y = x; for(j=0;j<NB_ERRORS;j++) { for(k=0;k<EXT_DEGREE;k++) {
if(y & (1<<k))//if((y>>k) & 1)
mat_set_coeff_to_one(H,j*EXT_DEGREE + 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 keypair(unsigned char * sk, unsigned char * pk) { int i, j, k, l; unsigned long * pt; gf_t *L, *Linv; poly_t g, *sqrtmod, *F; binmat_t R; gf_init(EXT_DEGREE);
//pick the support...
L = malloc(LENGTH * sizeof(gf_t)); for(i=0;i<LENGTH;i++)
L[i]=i;
gop_supr(LENGTH,L); do {
//pick the irreducible polynomial... g = poly_randgen_irred(NB_ERRORS, u8rnd); R = key_genmat(L,g);
if (R == NULL) poly_free(g); } while (R == NULL);
sqrtmod = poly_sqrtmod_init(g);
F = poly_syndrome_init(g, L, LENGTH);
// Each F[i] is the (precomputed) syndrome of the error vector with // a single '1' in i-th position.
// We do not store the F[i] as polynomials of degree NB_ERRORS, but // as binary vectors of length EXT_DEGREE * NB_ERRORS (this will // speed up the syndrome computation)
for (i = 0; i < LENGTH; ++i) {
memset(sk, 0, BITS_TO_LONG(CODIMENSION) * sizeof (long)); pt = (unsigned long *) sk; for (l = 0; l < NB_ERRORS; ++l) { k = (l * EXT_DEGREE) / BIT_SIZE_OF_LONG; j = (l * EXT_DEGREE) % BIT_SIZE_OF_LONG; pt[k] ^= poly_coeff(F[i], l) << j; if (j + EXT_DEGREE > BIT_SIZE_OF_LONG) pt[k + 1] ^= poly_coeff(F[i], l) >> (BIT_SIZE_OF_LONG - j); }
sk += BITS_TO_LONG(CODIMENSION) * sizeof (long); poly_free(F[i]);
}
free(F);
// We need the support L for decoding (decryption). In fact the // inverse is needed
Linv = malloc(LENGTH * sizeof (gf_t)); for (i = 0; i < LENGTH; ++i)
Linv[L[i]] = i;
memcpy(sk, Linv, LENGTH * sizeof (gf_t)); sk += LENGTH * sizeof (gf_t);
free(L); free(Linv);
memcpy(sk, g->coeff, (NB_ERRORS + 1) * sizeof (gf_t)); sk += (NB_ERRORS + 1) * sizeof (gf_t);
poly_free(g);
for (i = 0; i < NB_ERRORS; ++i) {
memcpy(sk, sqrtmod[i]->coeff, NB_ERRORS * sizeof (gf_t)); sk += NB_ERRORS * sizeof (gf_t);
poly_free(sqrtmod[i]); }
free(sqrtmod);
memcpy(pk, R->elem, R->alloc_size); mat_free(R);
return 1; }