예제 #1
0
BigInt PointGFp::get_affine_y() const
   {
   if(is_zero())
      throw Illegal_Transformation("Cannot convert zero point to affine");

   const BigInt& r2 = curve.get_r2();

   BigInt z3 = monty_mult(coord_z, monty_sqr(coord_z));
   z3 = inverse_mod(z3, curve.get_p());
   z3 = monty_mult(z3, r2);
   return monty_mult(coord_y, z3);
   }
예제 #2
0
bool PointGFp::on_the_curve() const
   {
   /*
   Is the point still on the curve?? (If everything is correct, the
   point is always on its curve; then the function will return true.
   If somehow the state is corrupted, which suggests a fault attack
   (or internal computational error), then return false.
   */

   if(is_zero())
      return true;

   BigInt y2 = monty_mult(monty_sqr(coord_y), 1);
   BigInt x3 = monty_mult(coord_x, monty_sqr(coord_x));

   BigInt ax = monty_mult(coord_x, curve.get_a_r());

   const BigInt& b_r = curve.get_b_r();

   BigInt z2 = monty_sqr(coord_z);

   if(coord_z == z2) // Is z equal to 1 (in Montgomery form)?
      {
      if(y2 != monty_mult(x3 + ax + b_r, 1))
         return false;
      }

   BigInt z3 = monty_mult(coord_z, z2);

   BigInt ax_z4 = monty_mult(ax, monty_sqr(z2));

   BigInt b_z6 = monty_mult(b_r, monty_sqr(z3));

   if(y2 != monty_mult(x3 + ax_z4 + b_z6, 1))
      return false;

   return true;
   }
예제 #3
0
파일: monty.c 프로젝트: DarkenCode/yafu
void zmModExp(z *a, z *b, z *u, z *nn)
{
	//computes a^b mod m = u using the right to left binary method
	//see, for instance, the handbook of applied cryptography
	//uses monty arith
	//a is already in monty rep, b doesn't need to be.
	z n,bb,aa,t;

	zInit(&aa);
	zInit(&bb);
	zInit(&n);
	zInit(&t);

	//overflow possibilities:
	//t ranges to 2x input 'a'
	//u needs at least as much space as modulus

	zCopy(&montyconst.one,&n);
	zCopy(a,&aa);

	zCopy(b,&bb);
	while (!isZero(&bb))
	{
		if (bb.val[0] & 0x1)
		{
			monty_mul(&n,&aa,&t,nn);
			zCopy(&t,&n);
		}
		zShiftRight(&bb,&bb,1);   //compute successive squares of a
		monty_sqr(&aa,&t,nn);
		zCopy(&t,&aa);
		if (aa.size < 0)
			aa.size *= -1;
	}
	zCopy(&n,u);

	zFree(&aa);
	zFree(&bb);
	zFree(&n);
	zFree(&t);
	return;
}
예제 #4
0
// Point addition
void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn)
   {
   if(is_zero())
      {
      coord_x = rhs.coord_x;
      coord_y = rhs.coord_y;
      coord_z = rhs.coord_z;
      return;
      }
   else if(rhs.is_zero())
      return;

   const BigInt& p = curve.get_p();

   BigInt& rhs_z2 = ws_bn[0];
   BigInt& U1 = ws_bn[1];
   BigInt& S1 = ws_bn[2];

   BigInt& lhs_z2 = ws_bn[3];
   BigInt& U2 = ws_bn[4];
   BigInt& S2 = ws_bn[5];

   BigInt& H = ws_bn[6];
   BigInt& r = ws_bn[7];

   monty_sqr(rhs_z2, rhs.coord_z);
   monty_mult(U1, coord_x, rhs_z2);
   monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2));

   monty_sqr(lhs_z2, coord_z);
   monty_mult(U2, rhs.coord_x, lhs_z2);
   monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2));

   H = U2;
   H -= U1;
   if(H.is_negative())
      H += p;

   r = S2;
   r -= S1;
   if(r.is_negative())
      r += p;

   if(H.is_zero())
      {
      if(r.is_zero())
         {
         mult2(ws_bn);
         return;
         }

      *this = PointGFp(curve); // setting myself to zero
      return;
      }

   monty_sqr(U2, H);

   monty_mult(S2, U2, H);

   U2 = monty_mult(U1, U2);

   monty_sqr(coord_x, r);
   coord_x -= S2;
   coord_x -= (U2 << 1);
   while(coord_x.is_negative())
      coord_x += p;

   U2 -= coord_x;
   if(U2.is_negative())
      U2 += p;

   monty_mult(coord_y, r, U2);
   coord_y -= monty_mult(S1, S2);
   if(coord_y.is_negative())
      coord_y += p;

   monty_mult(coord_z, monty_mult(coord_z, rhs.coord_z), H);
   }
예제 #5
0
// *this *= 2
void PointGFp::mult2(std::vector<BigInt>& ws_bn)
   {
   if(is_zero())
      return;
   else if(coord_y.is_zero())
      {
      *this = PointGFp(curve); // setting myself to zero
      return;
      }

   const BigInt& p = curve.get_p();

   BigInt& y_2 = ws_bn[0];
   BigInt& S = ws_bn[1];
   BigInt& z4 = ws_bn[2];
   BigInt& a_z4 = ws_bn[3];
   BigInt& M = ws_bn[4];
   BigInt& U = ws_bn[5];
   BigInt& x = ws_bn[6];
   BigInt& y = ws_bn[7];
   BigInt& z = ws_bn[8];

   monty_sqr(y_2, coord_y);

   monty_mult(S, coord_x, y_2);
   S <<= 2; // * 4
   while(S >= p)
      S -= p;

   monty_sqr(z4, monty_sqr(coord_z));
   monty_mult(a_z4, curve.get_a_r(), z4);

   M = 3 * monty_sqr(coord_x);
   M += a_z4;
   while(M >= p)
      M -= p;

   monty_sqr(x, M);
   x -= (S << 1);
   while(x.is_negative())
      x += p;

   monty_sqr(U, y_2);
   U <<= 3;
   while(U >= p)
      U -= p;

   S -= x;
   while(S.is_negative())
      S += p;

   monty_mult(y, M, S);
   y -= U;
   if(y.is_negative())
      y += p;

   monty_mult(z, coord_y, coord_z);
   z <<= 1;
   if(z >= p)
      z -= p;

   coord_x = x;
   coord_y = y;
   coord_z = z;
   }
예제 #6
0
파일: monty.c 프로젝트: DarkenCode/yafu
void zmModExpw(z *a, z *e, z *u, z *n, int k)
{
	//computes a^e mod m = u using the sliding window left to right binary method
	//see, for instance, the handbook of applied cryptography
	//uses monty arith
	//a is already in monty rep, b doesn't need to be.  k is the window size

	/*
	INPUT: g, e = (etet-1 . . . e1e0)2 with et = 1, and an integer k >= 1.
	OUTPUT: g^e.
	1. Precomputation.
	1.1 g1 = g, g2 = g^2.
	1.2 For i from 1 to (2^(k-1) - 1) do: g_{2i+1} =  g_{2i-1} * g2.
	2. A = 1, i = t.
	3. While i >= 0 do the following:
	3.1 If ei = 0 then do: A = A^2, i = i - 1.
	3.2 Otherwise (ei != 0), find the longest bitstring eiei-1 . . . el such that i-l+1 <= k
	and el = 1, and do the following:
	A = A^{2^{i-l+1}} * g_{eiei-1...el}2 , i = l - 1.
	4. Return(A).

	test -> 11749.  3 multiplications at i=7,4,0
	*/

	//need to allocate (2^(k-1) + 1) g's for precomputation.
	z *g, g2, ztmp;
	int numg, i, j, l, t, tmp1, tmp2;
	fp_digit utmp1;
	uint8 *bitarray;

	//overflow possibilities:
	//t ranges to 2x input 'a'
	//u needs at least as much space as modulus

	numg = (int)((1<<(k-1))+1);
	g = (z *)malloc(numg*sizeof(z));
	for (i=0;i<numg;i++)
		zInit(&g[i]);
	zInit(&g2);
	zInit(&ztmp);

	//precomputation
	zCopy(a,&g[0]);						//g[0] = a
	monty_sqr(a,&g2,n);					//g2 = a^2

	for (i=1;i<numg;i++)
		monty_mul(&g[i-1],&g2,&g[i],n);	//g[i] = g[i-1] * g2, where g[i] holds g^{2*i+1}

	zCopy(&montyconst.one,u);
	t = zBits(e);

	bitarray = (uint8 *)malloc(t * sizeof(uint8));
	//get e in one array
	for (i=0;i< e->size - 1;i++)
	{
		utmp1 = e->val[i];
		j=0;
		while (j<BITS_PER_DIGIT)
		{
			bitarray[BITS_PER_DIGIT*i+j] = (uint8)(utmp1 & 0x1);
			utmp1 >>= 1;
			j++;
		}
	}
	utmp1 = e->val[i];
	j=0;
	while (utmp1)
	{
		bitarray[BITS_PER_DIGIT*i+j] = (uint8)(utmp1 & 0x1);
		utmp1 >>= 1;
		j++;
	}

	i=t-1;
	while (i >= 0)
	{
		if (bitarray[i])
		{
			//find the longest bitstring ei,e1-1,...el such that i-l+1 <= k and el == 1
			l=i;
			if (i >= (k-1))
			{
				//protect against accessing bitarray past its boundaries
				for (j=k-1;j>0;j--)
				{
					if (bitarray[i-j])
					{
						//this is the longest possible string, exit
						l=i-j;
						break;
					}
				}
			}
			//now, bitarray[i] to bitarray[i-j] is the longest bitstring
			//figure out the g value to use corresponding to this bitstring
			tmp1 = 1;
			tmp2 = 0;
			for (j=l;j<=i;j++)
			{
				tmp2 += tmp1 * bitarray[j];
				tmp1 <<= 1;
			}
			tmp2 = (tmp2-1)/2;

			//do the operation A = A^{2^{i-l+1}} * g_{eiei-1...el}2
			for (j=0;j<(i-l+1);j++)
			{
				monty_sqr(u,&ztmp,n);
				zCopy(&ztmp,u);
			}
			monty_mul(u,&g[tmp2],&ztmp,n);
			zCopy(&ztmp,u);

			//decrement bit pointer
			i = l-1;
		}
		else
		{
			monty_sqr(u,&ztmp,n);
			zCopy(&ztmp,u);
			i--;
		}
	}

	for (i=0;i<numg;i++)
		zFree(&g[i]);
	free(g);
	zFree(&g2);
	zFree(&ztmp);
	free(bitarray);
	return;
}