示例#1
0
/*---------------------------------------------------------------------------*/
void
ecc_add(point_t * P0, point_t * P1, point_t * P2)
{
  NN_DIGIT Z0[NUMWORDS];
  NN_DIGIT Z1[NUMWORDS];
  NN_DIGIT Z2[NUMWORDS];

  p_clear(P0);
  NN_AssignZero(Z0, NUMWORDS);
  NN_AssignZero(Z1, NUMWORDS);
  NN_AssignZero(Z2, NUMWORDS);
  Z1[0] = 0x01;
  Z2[0] = 0x01;

#ifdef ADD_MIX
    c_add_mix(P0, Z0, P1, Z1, P2);
#else
    ecc_add_proj(P0, Z0, P1, Z1, P2, Z2);
#endif

  if(!Z_is_one(Z0)) {
    NN_ModInv(Z1, Z0, param.p, NUMWORDS);
    NN_ModMultOpt(Z0, Z1, Z1, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(P0->x, P0->x, Z0, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(Z0, Z0, Z1, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(P0->y, P0->y, Z0, param.p, param.omega, NUMWORDS);
  }

}
示例#2
0
/*
 * scalar point multiplication
 * P0 = n*basepoint
 * pointArray is array of basepoint, pointArray[0] = basepoint, pointArray[1] = 2*basepoint ...
 */
void
ecc_win_mul(point_t * P0, NN_DIGIT * n, point_t * pointArray)
{

  int16_t i, tmp;
  int8_t j;
  NN_DIGIT windex;
  NN_DIGIT Z0[NUMWORDS];
  NN_DIGIT Z1[NUMWORDS];
#ifndef REPEAT_DOUBLE
  int8_t k;
#endif

  p_clear(P0);

  /* Convert to Jprojective coordinate */
  NN_AssignZero(Z0, NUMWORDS);
  NN_AssignZero(Z1, NUMWORDS);
  Z1[0] = 0x01;

  tmp = NN_Digits(n, NUMWORDS);

  for(i = tmp - 1; i >= 0; i--) {
    for(j = NN_DIGIT_BITS/W_BITS - 1; j >= 0; j--) {

#ifndef REPEAT_DOUBLE
      for(k = 0; k < W_BITS; k++) {
        ecc_dbl_proj(P0, Z0, P0, Z0);
      }
#else
      ecc_m_dbl_projective(P0, Z0, W_BITS);
#endif

      windex = mask[j] & n[i];

      if(windex) {
        windex = windex >> (j*W_BITS);

#ifdef ADD_MIX
        c_add_mix(P0, Z0, P0, Z0, &(pointArray[windex-1]));
#else
	ecc_add_proj(P0, Z0, P0, Z0, &(pointArray[windex-1]), Z1);
#endif
      }
    }
  }


  /* Convert back to affine coordinate */
  if(!Z_is_one(Z0)) {
    NN_ModInv(Z1, Z0, param.p, NUMWORDS);
    NN_ModMultOpt(Z0, Z1, Z1, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(P0->x, P0->x, Z0, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(Z0, Z0, Z1, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(P0->y, P0->y, Z0, param.p, param.omega, NUMWORDS);
  }

}
示例#3
0
文件: ecc.c 项目: codeguru1/ecc
/*
 * P0 = n * P1
 */
void
ecc_mul ( point_t* P0, point_t* P1, NN_DIGIT* n )
{
	int16_t i, tmp;
	NN_DIGIT Z0[NUMWORDS];
	NN_DIGIT Z1[NUMWORDS];

	/* clear point */
	p_clear ( P0 );

	/* convert to Jprojective coordinate */
	NN_AssignZero ( Z0, NUMWORDS );
	NN_AssignZero ( Z1, NUMWORDS );
	Z1[0] = 0x01;

	tmp = NN_Bits ( n, NUMWORDS );

	for ( i = tmp-1; i >= 0; i-- )
	{
		ecc_dbl_proj ( P0, Z0, P0, Z0 );

		if ( b_testbit ( n, i ) )
		{

#ifdef ADD_MIX
			c_add_mix ( P0, Z0, P0, Z0, P1 );
#else
			ecc_add_proj ( P0, Z0, P0, Z0, P1, Z1 );
#endif
		}
	}

	/* convert back to affine coordinate */
	if ( !Z_is_one ( Z0 ) )
	{
		NN_ModInv ( Z1, Z0, param.p, NUMWORDS );
		NN_ModMultOpt ( Z0, Z1, Z1, param.p, param.omega, NUMWORDS );
		NN_ModMultOpt ( P0->x, P0->x, Z0, param.p, param.omega, NUMWORDS );
		NN_ModMultOpt ( Z0, Z0, Z1, param.p, param.omega, NUMWORDS );
		NN_ModMultOpt ( P0->y, P0->y, Z0, param.p, param.omega, NUMWORDS );
	}

}
示例#4
0
/*---------------------------------------------------------------------------*/
void
ecc_add_proj(point_t * P0, NN_DIGIT *Z0, point_t * P1, NN_DIGIT * Z1, point_t * P2, NN_DIGIT * Z2)
{
  NN_DIGIT n0[NUMWORDS];
  NN_DIGIT n1[NUMWORDS];
  NN_DIGIT n2[NUMWORDS];
  NN_DIGIT n3[NUMWORDS];
  NN_DIGIT n4[NUMWORDS];
  NN_DIGIT n5[NUMWORDS];
  NN_DIGIT n6[NUMWORDS];

  if(NN_Zero(Z1, NUMWORDS)) {
    p_copy(P0, P2);
    NN_Assign(Z0, Z2, NUMWORDS);
    return;
  }

  if(NN_Zero(Z2, NUMWORDS)) {
    p_copy(P0, P1);
    NN_Assign(Z0, Z1, NUMWORDS);
    return;
  }

  /* double */
  if(p_equal(P1, P2)) {
    ecc_dbl_proj(P0, Z0, P1, Z1);
    return;
  }

  /* add_proj
   * n1, n2
   */
  if(Z_is_one(Z2)) {
    /* n1 = P1->x, n2 = P1->y */
    NN_Assign(n1, P1->x, NUMWORDS);
    NN_Assign(n2, P1->y, NUMWORDS);
  } else {
    /* n1 = P1->x * Z2^2 */
    NN_ModSqrOpt(n0, Z2, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(n1, P1->x, n0, param.p, param.omega, NUMWORDS);
    /* n2 = P1->y * Z2^3 */
    NN_ModMultOpt(n0, n0, Z2, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(n2, P1->y, n0, param.p, param.omega, NUMWORDS);
  }

  /* n3, n4 */
  if(Z_is_one(Z1)) {
    /* n3 = P2->x, n4 = P2->y */
    NN_Assign(n3, P2->x, NUMWORDS);
    NN_Assign(n4, P2->y, NUMWORDS);
  } else {
    /* n3 = P2->x * Z1^2 */
    NN_ModSqrOpt(n0, Z1, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(n3, P2->x, n0, param.p, param.omega, NUMWORDS);
    /* n4 = P2->y * Z1^3 */
    NN_ModMultOpt(n0, n0, Z1, param.p, param.omega, NUMWORDS);
    NN_ModMultOpt(n4, P2->y, n0, param.p, param.omega, NUMWORDS);
  }

  /* n5 = n1 - n3, n6 = n2 - n4 */
  NN_ModSub(n5, n1, n3, param.p, NUMWORDS);
  NN_ModSub(n6, n2, n4, param.p, NUMWORDS);

  if(NN_Zero(n5, NUMWORDS)) {
    if(NN_Zero(n6, NUMWORDS)) {
      /* P1 and P2 are same point */
      ecc_dbl_proj(P0, Z0, P1, Z1);
      return;
    }
  } else {
    /* P1 is the inverse of P2 */
    NN_AssignZero(Z0, NUMWORDS);
    return;
  }

  /* 'n7' = n1 + n3, 'n8' = n2 + n4 */
  NN_ModAdd(n1, n1, n3, param.p, NUMWORDS);
  NN_ModAdd(n2, n2, n4, param.p, NUMWORDS);

  /* Z0 = Z1 * Z2 * n5 */
  if(Z_is_one(Z1) && Z_is_one(Z2)) {
    NN_Assign(Z0, n5, NUMWORDS);
  } else {
    if(Z_is_one(Z1)) {
      NN_Assign(n0, Z2, NUMWORDS);
    } else if(Z_is_one(Z2)) {
      NN_Assign(n0, Z1, NUMWORDS);
    } else {
      NN_ModMultOpt(n0, Z1, Z2, param.p, param.omega, NUMWORDS);
    }
    NN_ModMultOpt(Z0, n0, n5, param.p, param.omega, NUMWORDS);
  }

  /* P0->x = n6^2 - n5^2 * 'n7' */
  NN_ModSqrOpt(n0, n6, param.p, param.omega, NUMWORDS);
  NN_ModSqrOpt(n4, n5, param.p, param.omega, NUMWORDS);
  NN_ModMultOpt(n3, n1, n4, param.p, param.omega, NUMWORDS);
  NN_ModSub(P0->x, n0, n3, param.p, NUMWORDS);

  /* 'n9' = n5^2 * 'n7' - 2 * P0->x */
  NN_LShift(n0, P0->x, 1, NUMWORDS);
  NN_ModSmall(n0, param.p, NUMWORDS);
  NN_ModSub(n0, n3, n0, param.p, NUMWORDS);

  /* P0->y = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
  NN_ModMultOpt(n0, n0, n6, param.p, param.omega, NUMWORDS);
  NN_ModMultOpt(n5, n4, n5, param.p, param.omega, NUMWORDS);
  NN_ModMultOpt(n1, n2, n5, param.p, param.omega, NUMWORDS);
  NN_ModSub(n0, n0, n1, param.p, NUMWORDS);

  if((n0[0] % 2) == 1) {
    NN_Add(n0, n0, param.p, NUMWORDS);
  }

  NN_RShift(P0->y, n0, 1, NUMWORDS);

}
示例#5
0
/*---------------------------------------------------------------------------*/
void
ecc_dbl_proj(point_t * P0, NN_DIGIT *Z0, point_t * P1, NN_DIGIT * Z1)
{
  NN_DIGIT n0[NUMWORDS];
  NN_DIGIT n1[NUMWORDS];
  NN_DIGIT n2[NUMWORDS];
  NN_DIGIT n3[NUMWORDS];

  if(NN_Zero(Z1, NUMWORDS)) {
    NN_AssignZero(Z0, NUMWORDS);
    return;
  }

  // n1
  if(Z_is_one(Z1)) {
    /* n1 = 3 * P1->x^2 + param.E.a */
    NN_ModSqrOpt(n0, P1->x, param.p, param.omega, NUMWORDS);
    NN_LShift(n1, n0, 1, NUMWORDS);
    NN_ModSmall(n1, param.p, NUMWORDS);
    NN_ModAdd(n0, n0, n1, param.p, NUMWORDS);
    NN_ModAdd(n1, n0, param.E.a, param.p, NUMWORDS);
  } else {
    if(param.E.a_minus3) {
      /* for a = -3
       * n1 = 3 * (X1 + Z1^2) * (X1 - Z1^2) = 3 * X1^2 - 3 * Z1^4
       */
      NN_ModSqrOpt(n1, Z1, param.p, param.omega, NUMWORDS);
      NN_ModAdd(n0, P1->x, n1, param.p, NUMWORDS);
      NN_ModSub(n2, P1->x, n1, param.p, NUMWORDS);
      NN_ModMultOpt(n1, n0, n2, param.p, param.omega, NUMWORDS);
      NN_LShift(n0, n1, 1, NUMWORDS);
      NN_ModSmall(n0, param.p, NUMWORDS);
      NN_ModAdd(n1, n0, n1, param.p, NUMWORDS);

    } else if (param.E.a_zero) {
      /* n1 = 3 * P1->x^2 */
      NN_ModSqrOpt(n0, P1->x, param.p, param.omega, NUMWORDS);
      NN_LShift(n1, n0, 1, NUMWORDS);
      NN_ModSmall(n1, param.p, NUMWORDS);
      NN_ModAdd(n1, n0, n1, param.p, NUMWORDS);
    } else {
      /* n1 = 3 * P1->x^2 + param.E.a * Z1^4 */
      NN_ModSqrOpt(n0, P1->x, param.p, param.omega, NUMWORDS);
      NN_LShift(n1, n0, 1, NUMWORDS);
      NN_ModSmall(n1, param.p, NUMWORDS);
      NN_ModAdd(n0, n0, n1, param.p, NUMWORDS);
      NN_ModSqrOpt(n1, Z1, param.p, param.omega, NUMWORDS);
      NN_ModSqrOpt(n1, n1, param.p, param.omega, NUMWORDS);
      NN_ModMultOpt(n1, n1, param.E.a, param.p, param.omega, NUMWORDS);
      NN_ModAdd(n1, n1, n0, param.p, NUMWORDS);
    }
  }

  /* Z0 = 2 * P1->y * Z1 */
  if(Z_is_one(Z1)) {
    NN_Assign(n0, P1->y, NUMWORDS);
  } else {
    NN_ModMultOpt(n0, P1->y, Z1, param.p, param.omega, NUMWORDS);
  }
  NN_LShift(Z0, n0, 1, NUMWORDS);
  NN_ModSmall(Z0, param.p, NUMWORDS);

  /* n2 = 4 * P1->x * P1->y^2 */
  NN_ModSqrOpt(n3, P1->y, param.p, param.omega, NUMWORDS);
  NN_ModMultOpt(n2, P1->x, n3, param.p, param.omega, NUMWORDS);
  NN_LShift(n2, n2, 2, NUMWORDS);
  NN_ModSmall(n2, param.p, NUMWORDS);

  /* P0->x = n1^2 - 2 * n2 */
  NN_LShift(n0, n2, 1, NUMWORDS);
  NN_ModSmall(n0, param.p, NUMWORDS);
  NN_ModSqrOpt(P0->x, n1, param.p, param.omega, NUMWORDS);
  NN_ModSub(P0->x, P0->x, n0, param.p, NUMWORDS);

  /* n3 = 8 * P1->y^4 */
  NN_ModSqrOpt(n0, n3, param.p, param.omega, NUMWORDS);
  NN_LShift(n3, n0, 3, NUMWORDS);
  NN_ModSmall(n3, param.p, NUMWORDS);

  /* P0->y = n1 * (n2 - P0->x) - n3 */
  NN_ModSub(n0, n2, P0->x, param.p, NUMWORDS);
  NN_ModMultOpt(n0, n1, n0, param.p, param.omega, NUMWORDS);
  NN_ModSub(P0->y, n0, n3, param.p, NUMWORDS);

}