Вы находитесь на странице: 1из 18

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


01, /* extension degree 0 (!) never used */
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_deg(p) ((p)->deg)


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

b = coeff[d--];
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))
c = poly_copy(poly_gcd_aux(b, a));
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){
poly_addto_coeff(u0, i + j, gf_mul_fast(a, poly_coeff(u1, 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);

#endif
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 <stdlib.h>
#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 = 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<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;
}

Вам также может понравиться