Академический Документы
Профессиональный Документы
Культура Документы
h
#ifndef GF_H
#define GF_H
#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 */
#endif /* GF_H */
GF.C
#include <stdio.h>
#include <stdlib.h>
#include "gf.h"
/
***********************************************************************************
**********/
////////////////////////////////////GF
Functions.//////////////////////////////////////////////
/
***********************************************************************************
**********/
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;
}
int init_done = 0;
return 1;
}
POLY.H
#ifndef POLY_H
#define POLY_H
#include "gf.h"
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
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;
poly_t poly_copy(poly_t p) {
poly_t 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;
}
}
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_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);
}
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);
}
}
d = poly_deg(g);
poly_set_to_zero(res);
// 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);
}
}
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;
}
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;
}
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;
}
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;
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);
}
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);
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)
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;
}
return sqrt;
}
//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
#endif
MAT.C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "matrix.h"
/
***********************************************************************************
**********/
////////////////////////////////////MATRIX
Functions///////////////////////////////////////////
/
***********************************************************************************
**********/
void mat_free(binmat_t A)
{
free(A->elem);
free(A);
}
return(X);
}
int * mat_rref(binmat_t A)
{
int i,j,failcnt,findrow,max=A->coln - 1;
int *perm;
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.
}
return(perm);
}
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;
}
}
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"
/
***********************************************************************************
**********/
////////////////////////////////////KEY-GENERATION
Function////////////////////////////////////
/
***********************************************************************************
**********/
tmp = L[j];
L[j] = L[i];
L[i] = tmp;
}
}
n=LENGTH;//2^11=2048
r=NB_ERRORS*EXT_DEGREE;//32 x 11=352
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);
mat_free(H);
free(perm);
return (R);
}
gf_init(EXT_DEGREE);
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);
return 1;
}