Example #1
0
int ecCheck (const ecPoint *p)
	/* confirm that y^2 + x*y = x^3 + EC_B for point p */
{
	gfPoint t1, t2, t3, b;

	b[0] = 1; b[1] = EC_B;
	gfSquare (t1, p->y);
	gfMultiply (t2, p->x, p->y);
	gfAdd (t1, t1, t2);	/* t1 := y^2 + x*y */
	gfSquare (t2, p->x);
	gfMultiply (t3, t2, p->x);
	gfAdd (t2, t3, b);	/*/ t2 := x^3 + EC_B */
	return gfEqual (t1, t2);
} /* ecCheck */
Example #2
0
void RSCoder16::MakeEncoderMatrix()
{
    // Create Cauchy encoder generator matrix. Skip trivial "1" diagonal rows,
    // which would just copy source data to destination.
    for (uint I = 0; I < NR; I++)
        for (uint J = 0; J < ND; J++)
            MX[I * ND + J] = gfInv( gfAdd( (I+ND), J) );
}
Example #3
0
void ecSub (ecPoint *p, const ecPoint *r)
	/* sets p := p - r */
{
	ecPoint t;

	gfCopy (t.x, r->x);
	gfAdd  (t.y, r->x, r->y);
	ecAdd (p, &t);
} /* ecSub */
Example #4
0
int ecCalcY (ecPoint *p, int ybit)
	/* given the x coordinate of p, evaluate y such that y^2 + x*y = x^3 + EC_B */
{
	gfPoint a, b, t;

	b[0] = 1; b[1] = EC_B;
	if (p->x[0] == 0) {
		/* elliptic equation reduces to y^2 = EC_B: */
		gfSquareRoot (p->y, EC_B);
		return 1;
	}
	/* evaluate alpha = x^3 + b = (x^2)*x + EC_B: */
	gfSquare (t, p->x); /* keep t = x^2 for beta evaluation */
	gfMultiply (a, t, p->x);
	gfAdd (a, a, b); /* now a == alpha */
	if (a[0] == 0) {
		p->y[0] = 0;
		/* destroy potentially sensitive data: */
		gfClear (a); gfClear (t);
		return 1;
	}
	/* evaluate beta = alpha/x^2 = x + EC_B/x^2 */
	gfSmallDiv (t, EC_B);
	gfInvert (a, t);
	gfAdd (a, p->x, a); /* now a == beta */
	/* check if a solution exists: */
	if (gfTrace (a) != 0) {
		/* destroy potentially sensitive data: */
		gfClear (a); gfClear (t);
		return 0; /* no solution */
	}
	/* solve equation t^2 + t + beta = 0 so that gfYbit(t) == ybit: */
	gfQuadSolve (t, a);
	if (gfYbit (t) != ybit) {
		t[1] ^= 1;
	}
	/* compute y = x*t: */
	gfMultiply (p->y, p->x, t);
	/* destroy potentially sensitive data: */
	gfClear (a); gfClear (t);
	return 1;
} /* ecCalcY */
Example #5
0
void ecDouble (ecPoint *p)
	/* sets p := 2*p */
{
	gfPoint lambda, t1, t2;

	/* evaluate lambda = x + y/x: */
	gfInvert (t1, p->x);
	gfMultiply (lambda, p->y, t1);
	gfAdd (lambda, lambda, p->x);
	/* evaluate x3 = lambda^2 + lambda: */
	gfSquare (t1, lambda);
	gfAdd (t1, t1, lambda); /* now t1 = x3 */
	/* evaluate y3 = x^2 + lambda*x3 + x3: */
	gfSquare (p->y, p->x);
	gfMultiply (t2, lambda, t1);
	gfAdd (p->y, p->y, t2);
	gfAdd (p->y, p->y, t1);
	/* deposit the value of x3: */
	gfCopy (p->x, t1);
} /* ecDouble */
Example #6
0
static int gfSlowTrace (const gfPoint p)
	/* slowly evaluates to the trace of p (or an error code) */
{
	int i;
	gfPoint t;

	assert (logt != NULL && expt != NULL);
	assert (p != NULL);
	gfCopy (t, p);
	for (i = 1; i < GF_M; i++) {
		gfSquare (t, t);
		gfAdd (t, t, p);
	}
	return t[0] != 0;
} /* gfSlowTrace */
Example #7
0
void RSCoder16::MakeDecoderMatrix()
{
    // Create Cauchy decoder matrix. Skip trivial rows matching valid data
    // units and containing "1" on main diagonal. Such rows would just copy
    // source data to destination and they have no real value for us.
    // Include rows only for broken data units and replace them by first
    // available valid recovery code rows.
    for (uint Flag=0, R=ND, Dest=0; Flag < ND; Flag++)
        if (!ValidFlags[Flag]) // For every broken data unit.
        {
            while (!ValidFlags[R]) // Find a valid recovery unit.
                R++;
            for (uint J = 0; J < ND; J++) // And place its row to matrix.
                MX[Dest*ND + J] = gfInv( gfAdd(R,J) );
            Dest++;
            R++;
        }
}
Example #8
0
void ecAdd (ecPoint *p, const ecPoint *q)
	/* sets p := p + q */
{
	gfPoint lambda, t, tx, ty, x3;

	/* first check if there is indeed work to do (q != 0): */
	if (q->x[0] != 0 || q->y[0] != 0) {
		if (p->x[0] != 0 || p->y[0] != 0) {
			/* p != 0 and q != 0 */
			if (gfEqual (p->x, q->x)) {
				/* either p == q or p == -q: */
				if (gfEqual (p->y, q->y)) {
					/* points are equal; double p: */
					ecDouble (p);
				} else {
					/* must be inverse: result is zero */
					/* (should assert that q->y = p->x + p->y) */
					p->x[0] = p->y[0] = 0;
				}
			} else {
				/* p != 0, q != 0, p != q, p != -q */
				/* evaluate lambda = (y1 + y2)/(x1 + x2): */
				gfAdd (ty, p->y, q->y);
				gfAdd (tx, p->x, q->x);
				gfInvert (t, tx);
				gfMultiply (lambda, ty, t);
				/* evaluate x3 = lambda^2 + lambda + x1 + x2: */
				gfSquare (x3, lambda);
				gfAdd (x3, x3, lambda);
				gfAdd (x3, x3, tx);
				/* evaluate y3 = lambda*(x1 + x3) + x3 + y1: */
				gfAdd (tx, p->x, x3);
				gfMultiply (t, lambda, tx);
				gfAdd (t, t, x3);
				gfAdd (p->y, t, p->y);
				/* deposit the value of x3: */
				gfCopy (p->x, x3);
			}
		} else {
			/* just copy q into p: */
			gfCopy (p->x, q->x);
			gfCopy (p->y, q->y);
		}
	}
} /* ecAdd */
Example #9
0
// -----------------------------------------------------------------------------
int main ()
// -----------------------------------------------------------------------------
{
	// verify basic operations (mul, add, div):
	// a+b = b+a
	// a*b = b*a
	// a+(b+c) = (a+b)+c
	// a*(b*c) = (a*b)*c
	// a*c + b*c = (a+b)*c
	// a*(b/a) = b (if a != 0)
	gfInit();

	for (int a=0; a<GF_N; a++) {
		for (int b=0; b<GF_N; b++) {
			if (gfAdd(a, b) != gfAdd(b, a))
				return 1;
			if (gfMul(a, b) != gfMul(b, a))
				return 2;
			if (gfMul(a, b) != gfMul(b, a))
				return 2;
			for (int c=0; c<GF_N; c++) {
				if (gfAdd(a, gfAdd(b, c)) != gfAdd(gfAdd(a, b), c))
					return 3;
				if (gfMul(a, gfMul(b, c)) != gfMul(gfMul(a, b), c))
					return 4;
				if (gfAdd(gfMul(a, c), gfMul(b, c)) != gfMul(gfAdd(a, b), c))
					return 5;
			}
			if (a != GF_0)
				if (gfMul(a, gfDiv(b, a)) != b)
					return 6;
		}
	}

	// verify polynomial operations:
	// A = BQ + R
	const int M = GF_N;	// max deg
	gfExp  A[M+1];		int nA;
	gfExp  B[M+1];		int nB;
	gfExp  Q[M+1];		int nQ;
	gfExp  R1[M+2];
	gfExp* R = R1 + 1;	int nR;
	gfExp  Z[M+1];		int nZ;
	gfExp  Z1[2*M];		int nZ1;
	gfExp  Z2[2*M];		int nZ2;
	gfExp* P = R;		int nP;	// alias
	gfExp* N = B;		int nN;	// alias
	gfExp* Y = Q;		int nY;	// alias
	gfExp  Mem[8*(M+1) + 3];

// 	// -------------------- test polDiv, polMul, gfPolAdd(): --------------------
// 	for (int test=0; test<100000; test++) {
// 		// // clear all -- should not be required:
// 		// for (int i=0; i<=M; i++)
// 		// 	A[i] = B[i] = Q[i] = R[i] = Z[i] = 0;
// 		// R[-1] = 0;

// 		nB = randInt(0, M);
// 		nA = randInt(nB, M);
// 		randPol(A, nA);
// 		randPol(B, nB);
// 		if (gfPolDeg(B, nB) == -1)		// avoid dividing by B=0
// 			continue;
// 		nB = polDiv(A, nA, B, nB, Q, &nQ, R, &nR);
// 		nZ = gfPolMul(Q, nQ, B, nB, Z);				// B * Q
// 		if (nZ > nA)
// 			return 7;
// 		nZ = gfPolAdd(Z, nZ, R, nR, Z);				//       + R
// 		if (! polCmp(Z, A, nZ, nA))
// 			return 8;
// 	}

// 	// -------------------- test gfPolEEA(): --------------------
// 	for (int test=0; test<100000; test++) {
// 		nN = randInt(1, M);
// 		nA = randInt(0, nN-1);
// 		randPol(A, nA);
// 		randPol(N, nN);
// 		if (gfPolDeg(A, nA) == -1)		// avoid dividing by A=0
// 			continue;
// 		gfPolEEA(N, nN, A, nA, P, &nP, Q, &nQ, Mem);
// 		nZ1 = gfPolMul(P, nP, N, nN, Z1);
// 		nZ2 = gfPolMul(Q, nQ, A, nA, Z2);
// 		if (! polCmp(Z1, Z2, nZ1, nZ2))
// 			return 9;
// 	}

	// -------------------- test gfPolEvalSeq() against gfPolEval(): --------------------
	for (int test=0; test<10000; test++) {
		nA = randInt(0, GF_N - 2);	// limit of gfPolEvalSeq()
		nY = randInt(0, M);
		gfVec* Yv = Y;
		randPol(A, nA);
		gfExp x = GF_Z(1);//randE1();
		gfPolEvalSeq(A, nA, Yv, nY, x);
		for (int i=0; i<=nY; i++) {
			gfExp y2 = gfPolEval(A, nA, x);
			gfExp y1 = gfV2E[Yv[nY-i]];
			if (y2 != y1)
				return 10;
			x = gfMul(x, GF_Z(1));
		}
	}

	return 0;
}
Example #10
0
void ecNegate (ecPoint *p)
	/* sets p := -p */
{
	gfAdd (p->y, p->x, p->y);
} /* ecNegate */