Exemple #1
0
void ecMultiply (ecPoint *p, const vlPoint k)
	/* sets p := k*p */
{
	vlPoint h;
	int z, hi, ki;
	word16 i;
	ecPoint r;

	gfCopy (r.x, p->x); p->x[0] = 0;
	gfCopy (r.y, p->y); p->y[0] = 0;
	vlShortMultiply (h, k, 3);
	z = vlNumBits (h) - 1; /* so vlTakeBit (h, z) == 1 */
	i = 1;
	for (;;) {
		hi = vlTakeBit (h, i);
		ki = vlTakeBit (k, i);
		if (hi == 1 && ki == 0) {
			ecAdd (p, &r);
		}
		if (hi == 0 && ki == 1) {
			ecSub (p, &r);
		}
		if (i >= z) {
			break;
		}
		i++;
		ecDouble (&r);
	}
} /* ecMultiply */
Exemple #2
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 */
Exemple #3
0
error_t ecFullAdd(const EcDomainParameters *params, EcPoint *r, const EcPoint *s, const EcPoint *t)
{
   error_t error;

   //Check whether Sz == 0
   if(!mpiCompInt(&s->z, 0))
   {
      //Set R = T
      MPI_CHECK(mpiCopy(&r->x, &t->x));
      MPI_CHECK(mpiCopy(&r->y, &t->y));
      MPI_CHECK(mpiCopy(&r->z, &t->z));
   }
   //Check whether Tz == 0
   else if(!mpiCompInt(&t->z, 0))
   {
      //Set R = S
      MPI_CHECK(mpiCopy(&r->x, &s->x));
      MPI_CHECK(mpiCopy(&r->y, &s->y));
      MPI_CHECK(mpiCopy(&r->z, &s->z));
   }
   else
   {
      //Compute R = S + T
      EC_CHECK(ecAdd(params, r, s, t));

      //Check whether R == (0, 0, 0)
      if(!mpiCompInt(&r->x, 0) && !mpiCompInt(&r->y, 0) && !mpiCompInt(&r->z, 0))
      {
         //Compute R = 2 * S
         EC_CHECK(ecDouble(params, r, s));
      }
   }

end:
   //Return status code
   return error;
}
Exemple #4
0
error_t ecTwinMult(const EcDomainParameters *params, EcPoint *r,
   const Mpi *d0, const EcPoint *s, const Mpi *d1, const EcPoint *t)
{
   error_t error;
   int_t k;
   uint_t m;
   uint_t m0;
   uint_t m1;
   uint_t c0;
   uint_t c1;
   uint_t h0;
   uint_t h1;
   int_t u0;
   int_t u1;
   EcPoint spt;
   EcPoint smt;

   //Initialize EC points
   ecInit(&spt);
   ecInit(&smt);

   //Precompute SpT = S + T
   EC_CHECK(ecFullAdd(params, &spt, s, t));
   //Precompute SmT = S - T
   EC_CHECK(ecFullSub(params, &smt, s, t));

   //Let m0 be the bit length of d0
   m0 = mpiGetBitLength(d0);
   //Let m1 be the bit length of d1
   m1 = mpiGetBitLength(d1);
   //Let m = MAX(m0, m1)
   m = MAX(m0, m1);

   //Let c be a 2 x 6 binary matrix
   c0 = mpiGetBitValue(d0, m - 4);
   c0 |= mpiGetBitValue(d0, m - 3) << 1;
   c0 |= mpiGetBitValue(d0, m - 2) << 2;
   c0 |= mpiGetBitValue(d0, m - 1) << 3;
   c1 = mpiGetBitValue(d1, m - 4);
   c1 |= mpiGetBitValue(d1, m - 3) << 1;
   c1 |= mpiGetBitValue(d1, m - 2) << 2;
   c1 |= mpiGetBitValue(d1, m - 1) << 3;

   //Set R = (1, 1, 0)
   MPI_CHECK(mpiSetValue(&r->x, 1));
   MPI_CHECK(mpiSetValue(&r->y, 1));
   MPI_CHECK(mpiSetValue(&r->z, 0));

   //Calculate both multiplications at the same time
   for(k = m; k >= 0; k--)
   {
      //Compute h(0) = 16 * c(0,1) + 8 * c(0,2) + 4 * c(0,3) + 2 * c(0,4) + c(0,5)
      h0 = c0 & 0x1F;
      //Check whether c(0,0) == 1
      if(c0 & 0x20)
         h0 = 31 - h0;

      //Compute h(1) = 16 * c(1,1) + 8 * c(1,2) + 4 * c(1,3) + 2 * c(1,4) + c(1,5)
      h1 = c1 & 0x1F;
      //Check whether c(1,0) == 1
      if(c1 & 0x20)
         h1 = 31 - h1;

      //Compute u(0)
      if(h0 < ecTwinMultF(h1))
         u0 = 0;
      else if(c0 & 0x20)
         u0 = -1;
      else
         u0 = 1;

      //Compute u(1)
      if(h1 < ecTwinMultF(h0))
         u1 = 0;
      else if(c1 & 0x20)
         u1 = -1;
      else
         u1 = 1;

      //Update c matrix
      c0 <<= 1;
      c0 |= mpiGetBitValue(d0, k - 5);
      c0 ^= u0 ? 0x20 : 0x00;
      c1 <<= 1;
      c1 |= mpiGetBitValue(d1, k - 5);
      c1 ^= u1 ? 0x20 : 0x00;

      //Point doubling
      EC_CHECK(ecDouble(params, r, r));

      //Check u(0) and u(1)
      if(u0 == -1 && u1 == -1)
      {
         //Compute R = R - SpT
         EC_CHECK(ecFullSub(params, r, r, &spt));
      }
      else if(u0 == -1 && u1 == 0)
      {
         //Compute R = R - S
         EC_CHECK(ecFullSub(params, r, r, s));
      }
      else if(u0 == -1 && u1 == 1)
      {
         //Compute R = R - SmT
         EC_CHECK(ecFullSub(params, r, r, &smt));
      }
      else if(u0 == 0 && u1 == -1)
      {
         //Compute R = R - T
         EC_CHECK(ecFullSub(params, r, r, t));
      }
      else if(u0 == 0 && u1 == 1)
      {
         //Compute R = R + T
         EC_CHECK(ecFullAdd(params, r, r, t));
      }
      else if(u0 == 1 && u1 == -1)
      {
         //Compute R = R + SmT
         EC_CHECK(ecFullAdd(params, r, r, &smt));
      }
      else if(u0 == 1 && u1 == 0)
      {
         //Compute R = R + S
         EC_CHECK(ecFullAdd(params, r, r, s));
      }
      else if(u0 == 1 && u1 == 1)
      {
         //Compute R = R + SpT
         EC_CHECK(ecFullAdd(params, r, r, &spt));
      }
   }

end:
   //Release EC points
   ecFree(&spt);
   ecFree(&smt);

   //Return status code
   return error;
}
Exemple #5
0
error_t ecMult(const EcDomainParameters *params, EcPoint *r, const Mpi *d, const EcPoint *s)
{
   error_t error;
   uint_t i;
   Mpi h;

   //Initialize multiple precision integer
   mpiInit(&h);

   //Check whether d == 0
   if(!mpiCompInt(d, 0))
   {
      //Set R = (1, 1, 0)
      MPI_CHECK(mpiSetValue(&r->x, 1));
      MPI_CHECK(mpiSetValue(&r->y, 1));
      MPI_CHECK(mpiSetValue(&r->z, 0));
   }
   //Check whether d == 1
   else if(!mpiCompInt(d, 1))
   {
      //Set R = S
      MPI_CHECK(mpiCopy(&r->x, &s->x));
      MPI_CHECK(mpiCopy(&r->y, &s->y));
      MPI_CHECK(mpiCopy(&r->z, &s->z));
   }
   //Check whether Sz == 0
   else if(!mpiCompInt(&s->z, 0))
   {
      //Set R = (1, 1, 0)
      MPI_CHECK(mpiSetValue(&r->x, 1));
      MPI_CHECK(mpiSetValue(&r->y, 1));
      MPI_CHECK(mpiSetValue(&r->z, 0));
   }
   else
   {
      //Check whether Sz != 1
      if(mpiCompInt(&s->z, 1))
      {
         //Normalize S
         EC_CHECK(ecAffinify(params, r, s));
         EC_CHECK(ecProjectify(params, r, r));
      }
      else
      {
         //Set R = S
         MPI_CHECK(mpiCopy(&r->x, &s->x));
         MPI_CHECK(mpiCopy(&r->y, &s->y));
         MPI_CHECK(mpiCopy(&r->z, &s->z));
      }

//Left-to-right binary method
#if 0
      for(i = mpiGetBitLength(d) - 1; i >= 1; i--)
      {
         //Point doubling
         EC_CHECK(ecDouble(params, r, r));

         if(mpiGetBitValue(d, i - 1))
         {
            //Compute R = R + S
            EC_CHECK(ecFullAdd(params, r, r, s));
         }
      }
//Fast left-to-right binary method
#else
      //Precompute h = 3 * d
      MPI_CHECK(mpiAdd(&h, d, d));
      MPI_CHECK(mpiAdd(&h, &h, d));

      //Scalar multiplication
      for(i = mpiGetBitLength(&h) - 2; i >= 1; i--)
      {
         //Point doubling
         EC_CHECK(ecDouble(params, r, r));

         //Check whether h(i) == 1 and k(i) == 0
         if(mpiGetBitValue(&h, i) && !mpiGetBitValue(d, i))
         {
            //Compute R = R + S
            EC_CHECK(ecFullAdd(params, r, r, s));
         }
         //Check whether h(i) == 0 and k(i) == 1
         else if(!mpiGetBitValue(&h, i) && mpiGetBitValue(d, i))
         {
            //Compute R = R - S
            EC_CHECK(ecFullSub(params, r, r, s));
         }
      }
#endif
   }

end:
   //Release multiple precision integer
   mpiFree(&h);

   //Return status code
   return error;
}
Exemple #6
0
int ecSelfTest (int test_count)
	/* perform test_count self tests */
{
	int i, yb, nfail = 0, afail = 0, sfail = 0, cfail = 0, qfail = 0, pfail = 0, yfail = 0;
	ecPoint f, g, x, y;
	vlPoint m, n, p;
	clock_t elapsed = 0L;

	srand ((unsigned)(time(NULL) % 65521U));
	printf ("Executing %d curve self tests...", test_count);
	for (i = 0; i < test_count; i++) {
		ecRandom (&f);
		ecRandom (&g);
		vlRandom (m);
		vlRandom (n);

		/* negation test: -(-f) = f */
		ecCopy (&x, &f);
		ecNegate (&x);
		ecNegate (&x);
		if (!ecEqual (&x, &f)) {
			nfail++;
			/* printf ("Addition test #%d failed!\n", i); */
		}
		/* addition test: f+g = g+f */
		ecCopy (&x, &f); ecAdd (&x, &g);
		ecCopy (&y, &g); ecAdd (&y, &f);
		if (!ecEqual (&x, &y)) {
			afail++;
			/* printf ("Addition test #%d failed!\n", i); */
		}
		/* subtraction test: f-g = f+(-g) */
		ecCopy (&x, &f); ecSub (&x, &g);
		ecCopy (&y, &g); ecNegate (&y); ecAdd (&y, &f);
		if (!ecEqual (&x, &y)) {
			sfail++;
			/* printf ("Subtraction test #%d failed!\n", i); */
		}
		/* quadruplication test: 2*(2*f) = f + f + f + f */
		ecCopy (&x, &f); ecDouble (&x); ecDouble (&x);
		ecClear (&y); ecAdd (&y, &f); ecAdd (&y, &f); ecAdd (&y, &f); ecAdd (&y, &f);
		if (!ecEqual (&x, &y)) {
			qfail++;
			/* printf ("Quadruplication test #%d failed!\n", i); */
		}
		/* scalar multiplication commutativity test: m*(n*f) = n*(m*f) */
		ecCopy (&x, &f);
		ecCopy (&y, &f);
		elapsed -= clock ();
		ecMultiply (&x, n); ecMultiply (&x, m);
		ecMultiply (&y, m); ecMultiply (&y, n);
		elapsed += clock ();
		if (!ecEqual (&x, &y)) {
			cfail++;
			/* printf ("Commutativity test #%d failed!\n", i); */
		}
		/* y calculation test: */
		yb = ecYbit (&f);
		ecClear (&x);
		gfCopy (x.x, f.x);
		ecCalcY (&x, yb);
		if (!ecEqual (&f, &x)) {
			yfail++;
			/* printf ("Y calculation test #%d failed!\n", i); */
		}
		/* packing test: unpack (pack (f)) = f */
		ecPack (&f, p);
		ecUnpack (&x, p);
		if (!ecEqual (&f, &x)) {
			pfail++;
			/* printf ("Packing test #%d failed!\n", i); */
		}
	}
	printf (" done, scalar multiplication time: %.3f s/op.\n",
		(float)elapsed/CLOCKS_PER_SEC/(test_count?4*test_count:4));
	if (nfail) printf ("---> %d negations failed <---\n", nfail);
	if (afail) printf ("---> %d additions failed <---\n", afail);
	if (sfail) printf ("---> %d subtractions failed <---\n", sfail);
	if (qfail) printf ("---> %d quadruplications failed <---\n", qfail);
	if (cfail) printf ("---> %d commutativities failed <---\n", cfail);
	if (yfail) printf ("---> %d y calculations failed <---\n", yfail);
	if (pfail) printf ("---> %d packings failed <---\n", pfail);
	return nfail || afail || sfail || qfail || cfail || yfail || pfail;
} /* ecSelfTest */