Example #1
0
error_t rsadp(const RsaPrivateKey *key, const Mpi *c, Mpi *m)
{
   error_t error;
   Mpi m1;
   Mpi m2;
   Mpi h;

   //The ciphertext representative c shall be between 0 and n - 1
   if(mpiCompInt(c, 0) < 0 || mpiComp(c, &key->n) >= 0)
      return ERROR_OUT_OF_RANGE;

   //Initialize multiple-precision integers
   mpiInit(&m1);
   mpiInit(&m2);
   mpiInit(&h);

   //Use the Chinese remainder algorithm?
   if(key->n.size && key->p.size && key->q.size &&
      key->dp.size && key->dq.size && key->qinv.size)
   {
      //Compute m1 = c ^ dP mod p
      MPI_CHECK(mpiExpMod(&m1, c, &key->dp, &key->p));
      //Compute m2 = c ^ dQ mod q
      MPI_CHECK(mpiExpMod(&m2, c, &key->dq, &key->q));
      //Let h = (m1 - m2) * qInv mod p
      MPI_CHECK(mpiSub(&h, &m1, &m2));
      MPI_CHECK(mpiMulMod(&h, &h, &key->qinv, &key->p));
      //Let m = m2 + q * h
      MPI_CHECK(mpiMul(m, &key->q, &h));
      MPI_CHECK(mpiAdd(m, m, &m2));
   }
   //Use modular exponentiation?
   else if(key->n.size && key->d.size)
   {
      //Let m = c ^ d mod n
      error = mpiExpMod(m, c, &key->d, &key->n);
   }
   //Invalid parameters?
   else
   {
      //Report an error
      error = ERROR_INVALID_PARAMETER;
   }

end:
   //Free previously allocated memory
   mpiFree(&m1);
   mpiFree(&m2);
   mpiFree(&h);

   //Return status code
   return error;
}
Example #2
0
error_t ecSubMod(const EcDomainParameters *params, Mpi *r, const Mpi *a, const Mpi *b)
{
   error_t error;

   //Compute R = A - B
   MPI_CHECK(mpiSub(r, a, b));

   //Compute R = (A - B) mod p
   if(mpiCompInt(r, 0) < 0)
   {
       MPI_CHECK(mpiAdd(r, r, &params->p));
   }

end:
   //Return status code
   return error;
}
Example #3
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;
}
Example #4
0
error_t ecAdd(const EcDomainParameters *params, EcPoint *r, const EcPoint *s, const EcPoint *t)
{
   error_t error;
   Mpi t1;
   Mpi t2;
   Mpi t3;
   Mpi t4;
   Mpi t5;
   Mpi t6;
   Mpi t7;

   //Initialize multiple precision integers
   mpiInit(&t1);
   mpiInit(&t2);
   mpiInit(&t3);
   mpiInit(&t4);
   mpiInit(&t5);
   mpiInit(&t6);
   mpiInit(&t7);

   //Set t1 = Sx
   MPI_CHECK(mpiCopy(&t1, &s->x));
   //Set t2 = Sy
   MPI_CHECK(mpiCopy(&t2, &s->y));
   //Set t3 = Sz
   MPI_CHECK(mpiCopy(&t3, &s->z));
   //Set t4 = Tx
   MPI_CHECK(mpiCopy(&t4, &t->x));
   //Set t5 = Ty
   MPI_CHECK(mpiCopy(&t5, &t->y));

   //Check whether Tz != 1
   if(mpiCompInt(&t->z, 1))
   {
      //Compute t6 = Tz
      MPI_CHECK(mpiCopy(&t6, &t->z));
      //Compute t7 = t6^2
      EC_CHECK(ecSqrMod(params, &t7, &t6));
      //Compute t1 = t1 * t7
      EC_CHECK(ecMulMod(params, &t1, &t1, &t7));
      //Compute t7 = t6 * t7
      EC_CHECK(ecMulMod(params, &t7, &t6, &t7));
      //Compute t2 = t2 * t7
      EC_CHECK(ecMulMod(params, &t2, &t2, &t7));
   }

   //Compute t7 = t3^2
   EC_CHECK(ecSqrMod(params, &t7, &t3));
   //Compute t4 = t4 * t7
   EC_CHECK(ecMulMod(params, &t4, &t4, &t7));
   //Compute t7 = t3 * t7
   EC_CHECK(ecMulMod(params, &t7, &t3, &t7));
   //Compute t5 = t5 * t7
   EC_CHECK(ecMulMod(params, &t5, &t5, &t7));
   //Compute t4 = t1 - t4
   EC_CHECK(ecSubMod(params, &t4, &t1, &t4));
   //Compute t5 = t2 - t5
   EC_CHECK(ecSubMod(params, &t5, &t2, &t5));

   //Check whether t4 == 0
   if(!mpiCompInt(&t4, 0))
   {
      //Check whether t5 == 0
      if(!mpiCompInt(&t5, 0))
      {
         //Set R = (0, 0, 0)
         MPI_CHECK(mpiSetValue(&r->x, 0));
         MPI_CHECK(mpiSetValue(&r->y, 0));
         MPI_CHECK(mpiSetValue(&r->z, 0));
      }
      else
      {
         //Set R = (1, 1, 0)
         MPI_CHECK(mpiSetValue(&r->x, 1));
         MPI_CHECK(mpiSetValue(&r->y, 1));
         MPI_CHECK(mpiSetValue(&r->z, 0));
      }
   }
   else
   {
      //Compute t1 = 2 * t1 - t4
      EC_CHECK(ecAddMod(params, &t1, &t1, &t1));
      EC_CHECK(ecSubMod(params, &t1, &t1, &t4));
      //Compute t2 = 2 * t2 - t5
      EC_CHECK(ecAddMod(params, &t2, &t2, &t2));
      EC_CHECK(ecSubMod(params, &t2, &t2, &t5));

      //Check whether Tz != 1
      if(mpiCompInt(&t->z, 1))
      {
         //Compute t3 = t3 * t6
         EC_CHECK(ecMulMod(params, &t3, &t3, &t6));
      }

      //Compute t3 = t3 * t4
      EC_CHECK(ecMulMod(params, &t3, &t3, &t4));
      //Compute t7 = t4^2
      EC_CHECK(ecSqrMod(params, &t7, &t4));
      //Compute t4 = t4 * t7
      EC_CHECK(ecMulMod(params, &t4, &t4, &t7));
      //Compute t7 = t1 * t7
      EC_CHECK(ecMulMod(params, &t7, &t1, &t7));
      //Compute t1 = t5^2
      EC_CHECK(ecSqrMod(params, &t1, &t5));
      //Compute t1 = t1 - t7
      EC_CHECK(ecSubMod(params, &t1, &t1, &t7));
      //Compute t7 = t7 - 2 * t1
      EC_CHECK(ecAddMod(params, &t6, &t1, &t1));
      EC_CHECK(ecSubMod(params, &t7, &t7, &t6));
      //Compute t5 = t5 * t7
      EC_CHECK(ecMulMod(params, &t5, &t5, &t7));
      //Compute t4 = t2 * t4
      EC_CHECK(ecMulMod(params, &t4, &t2, &t4));
      //Compute t2 = t5 - t4
      EC_CHECK(ecSubMod(params, &t2, &t5, &t4));

      //Compute t2 = t2 / 2
      if(mpiIsEven(&t2))
      {
         MPI_CHECK(mpiShiftRight(&t2, 1));
      }
      else
      {
         MPI_CHECK(mpiAdd(&t2, &t2, &params->p));
         MPI_CHECK(mpiShiftRight(&t2, 1));
      }

      //Set Rx = t1
      MPI_CHECK(mpiCopy(&r->x, &t1));
      //Set Ry = t2
      MPI_CHECK(mpiCopy(&r->y, &t2));
      //Set Rz = t3
      MPI_CHECK(mpiCopy(&r->z, &t3));
   }

end:
   //Release multiple precision integers
   mpiFree(&t1);
   mpiFree(&t2);
   mpiFree(&t3);
   mpiFree(&t4);
   mpiFree(&t5);
   mpiFree(&t6);
   mpiFree(&t7);

   //Return status code
   return error;
}