Ejemplo n.º 1
0
Archivo: mpr.c Proyecto: aosm/X11
static int
mpr_docmp(mpr *op1, mpr *op2, int sign)
{
    int cmp, neg;
    mpi prod1, prod2;

    neg = 0;
    if (sign) {
	/* if op1 is negative */
	if (mpr_num(op1)->sign ^ mpr_den(op1)->sign) {
	    /* if op2 is positive */
	    if (!(mpr_num(op2)->sign ^ mpr_den(op2)->sign))
		return (-1);
	    else
		neg = 1;
	}
	/* if op2 is negative */
	else if (mpr_num(op2)->sign ^ mpr_den(op2)->sign)
	    return (1);
	/* else same sign */
    }

    /* if denominators are equal, compare numerators */
    if (mpi_cmpabs(mpr_den(op1), mpr_den(op2)) == 0) {
	cmp = mpi_cmpabs(mpr_num(op1), mpr_num(op2));
	if (cmp == 0)
	    return (0);
	if (sign && neg)
	    return (cmp < 0 ? 1 : -1);
	return (cmp);
    }

    memset(&prod1, '\0', sizeof(mpi));
    memset(&prod2, '\0', sizeof(mpi));

    /* "divide" op1 by op2
     * if result is smaller than 1, op1 is smaller than op2 */
    mpi_mul(&prod1, mpr_num(op1), mpr_den(op2));
    mpi_mul(&prod2, mpr_num(op2), mpr_den(op1));

    cmp = mpi_cmpabs(&prod1, &prod2);

    mpi_clear(&prod1);
    mpi_clear(&prod2);

    if (sign && neg)
	return (cmp < 0 ? 1 : -1);
    return (cmp);
}
Ejemplo n.º 2
0
Archivo: mpr.c Proyecto: aosm/X11
void
mpr_subi(mpr *rop, mpr *op1, long op2)
{
    mpi prod;

    memset(&prod, '\0', sizeof(mpi));

    mpi_muli(&prod, mpr_den(op1), op2);
    mpi_sub(mpr_num(rop), mpr_num(op1), &prod);
    mpi_clear(&prod);
}
Ejemplo n.º 3
0
Archivo: mpr.c Proyecto: aosm/X11
static void
mpr_addsub(mpr *rop, mpr *op1, mpr *op2, int sub)
{
    mpi prod1, prod2;

    memset(&prod1, '\0', sizeof(mpi));
    memset(&prod2, '\0', sizeof(mpi));

    mpi_mul(&prod1, mpr_num(op1), mpr_den(op2));
    mpi_mul(&prod2, mpr_num(op2), mpr_den(op1));

    if (sub)
	mpi_sub(mpr_num(rop), &prod1, &prod2);
    else
	mpi_add(mpr_num(rop), &prod1, &prod2);

    mpi_clear(&prod1);
    mpi_clear(&prod2);

    mpi_mul(mpr_den(rop), mpr_den(op1), mpr_den(op2));
}
Ejemplo n.º 4
0
/* Set the projective coordinates from X, Y, and Z into POINT.  If a
   coordinate is given as NULL, the value 0 is stored into point.  If
   POINT is given as NULL a new point object is allocated.  The
   coordinates X, Y, and Z are released.  Returns POINT or the newly
   allocated point object. */
mpi_point_t
gcry_mpi_point_snatch_set (mpi_point_t point,
                           gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
{
  if (!point)
    point = gcry_mpi_point_new (0);

  if (x)
    mpi_snatch (point->x, x);
  else
    mpi_clear (point->x);
  if (y)
    mpi_snatch (point->y, y);
  else
    mpi_clear (point->y);
  if (z)
    mpi_snatch (point->z, z);
  else
    mpi_clear (point->z);

  return point;
}
Ejemplo n.º 5
0
Archivo: mpr.c Proyecto: aosm/X11
void
mpr_div(mpr *rop, mpr *op1, mpr *op2)
{
    /* check if temporary storage is required */
    if (op1 == op2 && rop == op1) {
	mpi prod;

	memset(&prod, '\0', sizeof(mpi));

	mpi_mul(&prod, mpr_num(op1), mpr_den(op2));
	mpi_mul(mpr_den(rop), mpr_num(op2), mpr_den(op1));
	mpi_set(mpr_num(rop), &prod);

	mpi_clear(&prod);
    }
    else {
	mpi_mul(mpr_num(rop), mpr_num(op1), mpr_den(op2));
	mpi_mul(mpr_den(rop), mpr_num(op2), mpr_den(op1));
    }
}
Ejemplo n.º 6
0
Archivo: mpr.c Proyecto: aosm/X11
void
mpr_canonicalize(mpr *op)
{
    mpi gcd;

    memset(&gcd, '\0', sizeof(mpi));

    mpi_gcd(&gcd, mpr_num(op), mpr_den(op));
    if (mpi_cmpabsi(&gcd, 1)) {
	mpi_div(mpr_num(op), mpr_num(op), &gcd);
	mpi_div(mpr_den(op), mpr_den(op), &gcd);
    }

    if (op->den.sign) {
	op->num.sign = !op->num.sign;
	op->den.sign = 0;
    }

    mpi_clear(&gcd);
}
Ejemplo n.º 7
0
/* Scalar point multiplication - the main function for ECC.  If takes
   an integer SCALAR and a POINT as well as the usual context CTX.
   RESULT will be set to the resulting point. */
void
_gcry_mpi_ec_mul_point (mpi_point_t result,
                        gcry_mpi_t scalar, mpi_point_t point,
                        mpi_ec_t ctx)
{
#if 0
  /* Simple left to right binary method.  GECC Algorithm 3.27 */
  unsigned int nbits;
  int i;

  nbits = mpi_get_nbits (scalar);
  mpi_set_ui (result->x, 1);
  mpi_set_ui (result->y, 1);
  mpi_set_ui (result->z, 0);

  for (i=nbits-1; i >= 0; i--)
    {
      _gcry_mpi_ec_dup_point (result, result, ctx);
      if (mpi_test_bit (scalar, i) == 1)
        _gcry_mpi_ec_add_points (result, result, point, ctx);
    }

#else
  gcry_mpi_t x1, y1, z1, k, h, yy;
  unsigned int i, loops;
  mpi_point_struct p1, p2, p1inv;

  x1 = mpi_alloc_like (ctx->p);
  y1 = mpi_alloc_like (ctx->p);
  h  = mpi_alloc_like (ctx->p);
  k  = mpi_copy (scalar);
  yy = mpi_copy (point->y);

  if ( mpi_is_neg (k) )
    {
      k->sign = 0;
      ec_invm (yy, yy, ctx);
    }

  if (!mpi_cmp_ui (point->z, 1))
    {
      mpi_set (x1, point->x);
      mpi_set (y1, yy);
    }
  else
    {
      gcry_mpi_t z2, z3;

      z2 = mpi_alloc_like (ctx->p);
      z3 = mpi_alloc_like (ctx->p);
      ec_mulm (z2, point->z, point->z, ctx);
      ec_mulm (z3, point->z, z2, ctx);
      ec_invm (z2, z2, ctx);
      ec_mulm (x1, point->x, z2, ctx);
      ec_invm (z3, z3, ctx);
      ec_mulm (y1, yy, z3, ctx);
      mpi_free (z2);
      mpi_free (z3);
    }
  z1 = mpi_copy (mpi_const (MPI_C_ONE));

  mpi_mul (h, k, mpi_const (MPI_C_THREE)); /* h = 3k */
  loops = mpi_get_nbits (h);
  if (loops < 2)
    {
      /* If SCALAR is zero, the above mpi_mul sets H to zero and thus
         LOOPs will be zero.  To avoid an underflow of I in the main
         loop we set LOOP to 2 and the result to (0,0,0).  */
      loops = 2;
      mpi_clear (result->x);
      mpi_clear (result->y);
      mpi_clear (result->z);
    }
  else
    {
      mpi_set (result->x, point->x);
      mpi_set (result->y, yy);
      mpi_set (result->z, point->z);
    }
  mpi_free (yy); yy = NULL;

  p1.x = x1; x1 = NULL;
  p1.y = y1; y1 = NULL;
  p1.z = z1; z1 = NULL;
  point_init (&p2);
  point_init (&p1inv);

  for (i=loops-2; i > 0; i--)
    {
      _gcry_mpi_ec_dup_point (result, result, ctx);
      if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0)
        {
          point_set (&p2, result);
          _gcry_mpi_ec_add_points (result, &p2, &p1, ctx);
        }
      if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
        {
          point_set (&p2, result);
          /* Invert point: y = p - y mod p  */
          point_set (&p1inv, &p1);
          ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
          _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
        }
    }

  point_free (&p1);
  point_free (&p2);
  point_free (&p1inv);
  mpi_free (h);
  mpi_free (k);
#endif
}
Ejemplo n.º 8
0
int mpi_fromstr(MPI val, const char *str)
{
	int hexmode = 0, sign = 0, prepend_zero = 0, i, j, c, c1, c2;
	unsigned nbits, nbytes, nlimbs;
	mpi_limb_t a;

	if (*str == '-') {
		sign = 1;
		str++;
	}
	if (*str == '0' && str[1] == 'x')
		hexmode = 1;
	else
		return -EINVAL;	
	str += 2;

	nbits = strlen(str) * 4;
	if (nbits % 8)
		prepend_zero = 1;
	nbytes = (nbits + 7) / 8;
	nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
	if (val->alloced < nlimbs)
		if (!mpi_resize(val, nlimbs))
			return -ENOMEM;
	i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
	i %= BYTES_PER_MPI_LIMB;
	j = val->nlimbs = nlimbs;
	val->sign = sign;
	for (; j > 0; j--) {
		a = 0;
		for (; i < BYTES_PER_MPI_LIMB; i++) {
			if (prepend_zero) {
				c1 = '0';
				prepend_zero = 0;
			} else
				c1 = *str++;
			assert(c1);
			c2 = *str++;
			assert(c2);
			if (c1 >= '0' && c1 <= '9')
				c = c1 - '0';
			else if (c1 >= 'a' && c1 <= 'f')
				c = c1 - 'a' + 10;
			else if (c1 >= 'A' && c1 <= 'F')
				c = c1 - 'A' + 10;
			else {
				mpi_clear(val);
				return 1;
			}
			c <<= 4;
			if (c2 >= '0' && c2 <= '9')
				c |= c2 - '0';
			else if (c2 >= 'a' && c2 <= 'f')
				c |= c2 - 'a' + 10;
			else if (c2 >= 'A' && c2 <= 'F')
				c |= c2 - 'A' + 10;
			else {
				mpi_clear(val);
				return 1;
			}
			a <<= 8;
			a |= c;
		}
		i = 0;

		val->d[j - 1] = a;
	}

	return 0;
}
Ejemplo n.º 9
0
/****************
 * Fill the mpi VAL from the hex string in STR.
 */
static int
mpi_fromstr (gcry_mpi_t val, const char *str)
{
  int sign = 0;
  int prepend_zero = 0;
  int i, j, c, c1, c2;
  unsigned int nbits, nbytes, nlimbs;
  mpi_limb_t a;

  if ( *str == '-' )
    {
      sign = 1;
      str++;
    }

  /* Skip optional hex prefix.  */
  if ( *str == '0' && str[1] == 'x' )
    str += 2;

  nbits = 4 * strlen (str);
  if ((nbits % 8))
    prepend_zero = 1;

  nbytes = (nbits+7) / 8;
  nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;

  if ( val->alloced < nlimbs )
    mpi_resize (val, nlimbs);

  i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
  i %= BYTES_PER_MPI_LIMB;
  j = val->nlimbs = nlimbs;
  val->sign = sign;
  for (; j > 0; j--)
    {
      a = 0;
      for (; i < BYTES_PER_MPI_LIMB; i++)
        {
          if (prepend_zero)
            {
              c1 = '0';
              prepend_zero = 0;
	    }
          else
            c1 = *str++;

          if (!c1)
            {
              mpi_clear (val);
              return 1;  /* Error.  */
	    }
          c2 = *str++;
          if (!c2)
            {
              mpi_clear (val);
              return 1;  /* Error.  */
	    }
          if ( c1 >= '0' && c1 <= '9' )
            c = c1 - '0';
          else if ( c1 >= 'a' && c1 <= 'f' )
            c = c1 - 'a' + 10;
          else if ( c1 >= 'A' && c1 <= 'F' )
            c = c1 - 'A' + 10;
          else
            {
              mpi_clear (val);
              return 1;  /* Error.  */
	    }
          c <<= 4;
          if ( c2 >= '0' && c2 <= '9' )
            c |= c2 - '0';
          else if( c2 >= 'a' && c2 <= 'f' )
            c |= c2 - 'a' + 10;
          else if( c2 >= 'A' && c2 <= 'F' )
            c |= c2 - 'A' + 10;
          else
            {
              mpi_clear(val);
              return 1;  /* Error. */
	    }
          a <<= 8;
          a |= c;
	}
      i = 0;
      val->d[j-1] = a;
    }

  return 0;  /* Okay.  */
}