• No results found

Print

N/A
N/A
Protected

Academic year: 2021

Share "Print"

Copied!
18
0
0

Loading.... (view fulltext now)

Full text

(1)

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] = {

(2)

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)

(3)

{

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

(4)

#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;

(5)

// 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;

(6)

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]);

(7)

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))

(8)

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;

(9)

}

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){

(10)

}

// 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]);

(11)

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;

(12)

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);

(13)

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;

(14)

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

(15)

{

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

(16)

#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++) {

(17)

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);

(18)

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; }

References

Related documents

Jacada WorkSpace is well suited for contact center environments where agents are either burdened with multiple desktop applications or where complex business rules (whether

The serial adapter supports different interface types which are selected by placement of jumpers on the 

Corrosion of Materials Other than Metal; Early Corrosion Studies; Fundamentals; Electrochemical Principles; Electromotive Force; Ionization; The Corrosion Cell; Oxidation and

1 DEPRESS FOOT PEDAL 2 DISENGAGE ATTACHMENT 3 CHECK OIL INDICATOR LIGHTS RED BLACK RED RED BLACK BLACK BLACK BLACK WHITE WHITE RED RED YELLOW RED WHITE WHITE BLACK RED

If the test result is within the Control Solution Range printed on the strip vial label, RIGHTEST Blood Glucose Monitoring System passes the Quality Control Test and

The Facilities work program includes all aspects of company work space

[r]

◆ Auto-antifreeze: To prevent the pipes and pumps from being frozen, the unit will defrost automatically when it meets the condition as follows: the ambient temperature is