Ejemplo n.º 1
0
void ec_double (ec_point *p)
	/* sets p := 2*p */
{
	gf_point lambda, t1, t2;

	/* evaluate lambda = x + y/x: */
	gf_invert (t1, p->x);
	gf_multiply (lambda, p->y, t1);
	gf_add (lambda, lambda, p->x);
	/* evaluate x3 = lambda^2 + lambda: */
	gf_square (t1, lambda);
	gf_add (t1, t1, lambda); /* now t1 = x3 */
	/* evaluate y3 = x^2 + lambda*x3 + x3: */
	gf_square (p->y, p->x);
	gf_multiply (t2, lambda, t1);
	gf_add (p->y, p->y, t2);
	gf_add (p->y, p->y, t1);
	/* deposit the value of x3: */
	gf_copy (p->x, t1);
} /* ec_double */
Ejemplo n.º 2
0
// carré de p modulo un certain polynôme g, sq[] contient les carrés
// modulo g de la base canonique des polynômes de degré < d, où d est
// le degré de g. La table sq[] sera calculée par 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);

    // termes de bas degré
    for (i = 0; i < d / 2; ++i)
        poly_set_coeff(res, i * 2, gf_square(poly_coeff(p, i)));

    // termes de haut degré
    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)));
        }
    }

    // mise à jour du degré
    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);
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
void ec_add (ec_point *p, const ec_point *q)
	/* sets p := p + q */
{
	gf_point 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 (gf_equal (p->x, q->x)) {
				/* either p == q or p == -q: */
				if (gf_equal (p->y, q->y)) {
					/* points are equal; double p: */
					ec_double (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): */
				gf_add (ty, p->y, q->y);
				gf_add (tx, p->x, q->x);
				gf_invert (t, tx);
				gf_multiply (lambda, ty, t);
				/* evaluate x3 = lambda^2 + lambda + x1 + x2: */
				gf_square (x3, lambda);
				gf_add (x3, x3, lambda);
				gf_add (x3, x3, tx);
				/* evaluate y3 = lambda*(x1 + x3) + x3 + y1: */
				gf_add (tx, p->x, x3);
				gf_multiply (t, lambda, tx);
				gf_add (t, t, x3);
				gf_add (p->y, t, p->y);
				/* deposit the value of x3: */
				gf_copy (p->x, x3);
			}
		} else {
			/* just copy q into p: */
			gf_copy (p->x, q->x);
			gf_copy (p->y, q->y);
		}
	}
} /* ec_add */
Ejemplo n.º 5
0
int ec_calcy (ec_point *p, int ybit)
	/* given the x coordinate of p, evaluate y such that y^2 + x*y = x^3 + EC_B */
{
	gf_point a, b, t;

	b[0] = 1; b[1] = EC_B;
	if (p->x[0] == 0) {
		/* elliptic equation reduces to y^2 = EC_B: */
		gf_squareroot (p->y, EC_B);
		return 1;
	}
	/* evaluate alpha = x^3 + b = (x^2)*x + EC_B: */
	gf_square (t, p->x); /* keep t = x^2 for beta evaluation */
	gf_multiply (a, t, p->x);
	gf_add (a, a, b); /* now a == alpha */
	if (a[0] == 0) {
		p->y[0] = 0;
		/* destroy potentially sensitive data: */
		gf_clear (a); gf_clear (t);
		return 1;
	}
	/* evaluate beta = alpha/x^2 = x + EC_B/x^2 */
	gf_smalldiv (t, EC_B);
	gf_invert (a, t);
	gf_add (a, p->x, a); /* now a == beta */
	/* check if a solution exists: */
	if (gf_trace (a) != 0) {
		/* destroy potentially sensitive data: */
		gf_clear (a); gf_clear (t);
		return 0; /* no solution */
	}
	/* solve equation t^2 + t + beta = 0 so that gf_ybit(t) == ybit: */
	gf_quadsolve (t, a);
	if (gf_ybit (t) != ybit) {
		t[1] ^= 1;
	}
	/* compute y = x*t: */
	gf_multiply (p->y, p->x, t);
	/* destroy potentially sensitive data: */
	gf_clear (a); gf_clear (t);
	return 1;
} /* ec_calcy */