Пример #1
0
void ecFree(EcPoint *r)
{
   //Release previsoulsy allocated resources
   mpiFree(&r->x);
   mpiFree(&r->y);
   mpiFree(&r->z);
}
Пример #2
0
bool_t ecIsPointAffine(const EcDomainParameters *params, const EcPoint *s)
{
   error_t error;
   Mpi t1;
   Mpi t2;

   //Initialize multiple precision integers
   mpiInit(&t1);
   mpiInit(&t2);

   //Compute t1 = (Sx^3 + a * Sx + b) mod p
   EC_CHECK(ecSqrMod(params, &t1, &s->x));
   EC_CHECK(ecMulMod(params, &t1, &t1, &s->x));
   EC_CHECK(ecMulMod(params, &t2, &params->a, &s->x));
   EC_CHECK(ecAddMod(params, &t1, &t1, &t2));
   EC_CHECK(ecAddMod(params, &t1, &t1, &params->b));

   //Compute t2 = Sy^2
   EC_CHECK(ecSqrMod(params, &t2, &s->y));

   //Check whether the point is on the elliptic curve
   if(mpiComp(&t1, &t2))
      error = ERROR_FAILURE;

end:
   //Release multiple precision integers
   mpiFree(&t1);
   mpiFree(&t2);

   //Return TRUE if the affine point S is on the curve, else FALSE
   return error ? FALSE : TRUE;
}
Пример #3
0
void ecFreeDomainParameters(EcDomainParameters *params)
{
   //Release previsoulsy allocated resources
   mpiFree(&params->p);
   mpiFree(&params->a);
   mpiFree(&params->b);
   ecFree(&params->g);
   mpiFree(&params->q);
}
Пример #4
0
void dhFreeParameters(DhParameters *params)
{
   //Free multiple precision integers
   mpiFree(&params->p);
   mpiFree(&params->g);
   mpiFree(&params->xa);
   mpiFree(&params->ya);
   mpiFree(&params->yb);
}
Пример #5
0
void dhFree(DhContext *context)
{
   //Release Diffie-Hellman parameters
   mpiFree(&context->params.p);
   mpiFree(&context->params.g);
   //Release private and public values
   mpiFree(&context->xa);
   mpiFree(&context->ya);
   mpiFree(&context->yb);
}
Пример #6
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;
}
Пример #7
0
error_t dhCheckPublicKey(DhParameters *params, const Mpi *publicKey)
{
   error_t error;
   Mpi a;

   //Initialize multiple precision integer
   mpiInit(&a);
   //Precompute p - 1
   error = mpiSubInt(&a, &params->p, 1);

   //Check status
   if(!error)
   {
      //Reject weak public values 1 and p - 1
      if(mpiCompInt(publicKey, 1) <= 0)
         error = ERROR_ILLEGAL_PARAMETER;
      else if(mpiComp(publicKey, &a) >= 0)
         error = ERROR_ILLEGAL_PARAMETER;
   }

   //Free previously allocated resources
   mpiFree(&a);
   //Return status code
   return error;
}
Пример #8
0
void rsaFreePrivateKey(RsaPrivateKey *key)
{
   //Free multiple precision integers
   mpiFree(&key->n);
   mpiFree(&key->e);
   mpiFree(&key->d);
   mpiFree(&key->p);
   mpiFree(&key->q);
   mpiFree(&key->dp);
   mpiFree(&key->dq);
   mpiFree(&key->qinv);
}
Пример #9
0
error_t ecAffinify(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
{
   error_t error;
   Mpi a;
   Mpi b;

   //Point at the infinity?
   if(!mpiCompInt(&s->z, 0))
      return ERROR_INVALID_PARAMETER;

   //Initialize multiple precision integers
   mpiInit(&a);
   mpiInit(&b);

   //Compute a = 1/Sz mod p
   MPI_CHECK(mpiInvMod(&a, &s->z, &params->p));

   //Set Rx = a^2 * Sx mod p
   EC_CHECK(ecSqrMod(params, &b, &a));
   EC_CHECK(ecMulMod(params, &r->x, &b, &s->x));

   //Set Ry = a^3 * Sy mod p
   EC_CHECK(ecMulMod(params, &b, &b, &a));
   EC_CHECK(ecMulMod(params, &r->y, &b, &s->y));

   //Set Rz = 1
   MPI_CHECK(mpiSetValue(&r->z, 1));

end:
   //Release multiple precision integers
   mpiFree(&a);
   mpiFree(&b);

   //Return status code
   return error;
}
Пример #10
0
error_t dhComputeSharedSecret(DhContext *context,
   uint8_t *output, size_t outputSize, size_t *outputLength)
{
   error_t error;
   size_t k;
   Mpi z;

   //Debug message
   TRACE_DEBUG("Computing Diffie-Hellman shared secret...\r\n");

   //Get the length in octets of the prime modulus
   k = mpiGetByteLength(&context->params.p);

   //Make sure that the output buffer is large enough
   if(outputSize < k)
      return ERROR_INVALID_LENGTH;

   //The multiple precision integer must be initialized before it can be used
   mpiInit(&z);

   //Start of exception handling block
   do
   {
      //Calculate the shared secret key (k = yb ^ xa mod p)
      error = mpiExpMod(&z, &context->yb, &context->xa, &context->params.p);
      //Any error to report?
      if(error) return error;

      //Convert the resulting integer to an octet string
      error = mpiWriteRaw(&z, output, k);
      //Conversion failed?
      if(error) return error;

      //Length of the resulting shared secret
      *outputLength = k;

      //Debug message
      TRACE_DEBUG("  Shared secret (%" PRIuSIZE " bytes):\r\n", *outputLength);
      TRACE_DEBUG_ARRAY("    ", output, *outputLength);

      //End of exception handling block
   } while(0);

   //Release previously allocated resources
   mpiFree(&z);
   //Return status code
   return error;
}
Пример #11
0
void rsaFreePublicKey(RsaPublicKey *key)
{
   //Free multiple precision integers
   mpiFree(&key->n);
   mpiFree(&key->e);
}
Пример #12
0
error_t rsassaPkcs1v15Verify(const RsaPublicKey *key, const HashAlgo *hash,
   const uint8_t *digest, const uint8_t *signature, size_t signatureLength)
{
   error_t error;
   uint_t k;
   uint8_t *em;
   const uint8_t *oid;
   size_t oidLength;
   const uint8_t *d;
   size_t dLength;
   Mpi s;
   Mpi m;

   //Check parameters
   if(key == NULL || hash == NULL || digest == NULL || signature == NULL)
      return ERROR_INVALID_PARAMETER;

   //Debug message
   TRACE_DEBUG("RSA PKCS #1 v1.5 signature verification...\r\n");
   TRACE_DEBUG("  Modulus:\r\n");
   TRACE_DEBUG_MPI("    ", &key->n);
   TRACE_DEBUG("  Public exponent:\r\n");
   TRACE_DEBUG_MPI("    ", &key->e);
   TRACE_DEBUG("  Message digest:\r\n");
   TRACE_DEBUG_ARRAY("    ", digest, hash->digestSize);
   TRACE_DEBUG("  Signature:\r\n");
   TRACE_DEBUG_ARRAY("    ", signature, signatureLength);

   //Initialize multiple-precision integers
   mpiInit(&s);
   mpiInit(&m);

   //Get the length in octets of the modulus n
   k = mpiGetByteLength(&key->n);

   //Check the length of the signature
   if(signatureLength != k)
      return ERROR_INVALID_LENGTH;

   //Allocate a memory buffer to hold the encoded message
   em = osAllocMem(k);
   //Failed to allocate memory?
   if(!em) return ERROR_OUT_OF_MEMORY;

   //Start of exception handling block
   do
   {
      //Convert the signature to an integer signature representative s
      error = mpiReadRaw(&s, signature, signatureLength);
      //Conversion failed?
      if(error) break;

      //Apply the RSAVP1 verification primitive
      error = rsavp1(key, &s, &m);
      //Any error to report?
      if(error) break;

      //Convert the message representative m to an encoded message EM of length k octets
      error = mpiWriteRaw(&m, em, k);
      //Conversion failed?
      if(error) break;

      //Debug message
      TRACE_DEBUG("  Encoded message\r\n");
      TRACE_DEBUG_ARRAY("    ", em, k);

      //Parse the encoded message EM
      error = emsaPkcs1v15Decode(em, k, &oid, &oidLength, &d, &dLength);
      //Any error to report?
      if(error) break;

      //Assume an error...
      error = ERROR_INVALID_SIGNATURE_ALGO;
      //Ensure the hash algorithm identifier matches the OID
      if(oidComp(oid, oidLength, hash->oid, hash->oidSize))
         break;
      //Check the length of the digest
      if(dLength != hash->digestSize)
         break;

      //Compare the message digest
      error = memcmp(digest, d, dLength) ? ERROR_INVALID_SIGNATURE : NO_ERROR;

      //End of exception handling block
   } while(0);

   //Release multiple precision integers
   mpiFree(&s);
   mpiFree(&m);
   //Free previously allocated memory
   osFreeMem(em);

   //Return status code
   return error;
}
Пример #13
0
error_t rsassaPkcs1v15Sign(const RsaPrivateKey *key, const HashAlgo *hash,
   const uint8_t *digest, uint8_t *signature, size_t *signatureLength)
{
   error_t error;
   uint_t k;
   uint8_t *em;
   Mpi m;
   Mpi s;

   //Check parameters
   if(key == NULL || hash == NULL || digest == NULL)
      return ERROR_INVALID_PARAMETER;
   if(signature == NULL || signatureLength == NULL)
      return ERROR_INVALID_PARAMETER;

   //Debug message
   TRACE_DEBUG("RSA PKCS #1 v1.5 signature generation...\r\n");
   TRACE_DEBUG("  Modulus:\r\n");
   TRACE_DEBUG_MPI("    ", &key->n);
   TRACE_DEBUG("  Public exponent:\r\n");
   TRACE_DEBUG_MPI("    ", &key->e);
   TRACE_DEBUG("  Private exponent:\r\n");
   TRACE_DEBUG_MPI("    ", &key->d);
   TRACE_DEBUG("  Prime 1:\r\n");
   TRACE_DEBUG_MPI("    ", &key->p);
   TRACE_DEBUG("  Prime 2:\r\n");
   TRACE_DEBUG_MPI("    ", &key->q);
   TRACE_DEBUG("  Prime exponent 1:\r\n");
   TRACE_DEBUG_MPI("    ", &key->dp);
   TRACE_DEBUG("  Prime exponent 2:\r\n");
   TRACE_DEBUG_MPI("    ", &key->dq);
   TRACE_DEBUG("  Coefficient:\r\n");
   TRACE_DEBUG_MPI("    ", &key->qinv);
   TRACE_DEBUG("  Message digest:\r\n");
   TRACE_DEBUG_ARRAY("    ", digest, hash->digestSize);

   //Initialize multiple-precision integers
   mpiInit(&m);
   mpiInit(&s);

   //Get the length in octets of the modulus n
   k = mpiGetByteLength(&key->n);
   //Point to the buffer where the encoded message EM will be generated
   em = signature;

   //Apply the EMSA-PKCS1-v1.5 encoding operation
   error = emsaPkcs1v15Encode(hash, digest, em, k);
   //Any error to report?
   if(error) return error;

   //Debug message
   TRACE_DEBUG("  Encoded message\r\n");
   TRACE_DEBUG_ARRAY("    ", em, k);

   //Start of exception handling block
   do
   {
      //Convert the encoded message EM to an integer message representative m
      error = mpiReadRaw(&m, em, k);
      //Conversion failed?
      if(error) break;

      //Apply the RSASP1 signature primitive
      error = rsasp1(key, &m, &s);
      //Any error to report?
      if(error) break;

      //Convert the signature representative s to a signature of length k octets
      error = mpiWriteRaw(&s, signature, k);
      //Conversion failed?
      if(error) break;

      //Length of the resulting signature
      *signatureLength = k;

      //Debug message
      TRACE_DEBUG("  Signature:\r\n");
      TRACE_DEBUG_ARRAY("    ", signature, *signatureLength);

      //End of exception handling block
   } while(0);

   //Free previously allocated memory
   mpiFree(&m);
   mpiFree(&s);

   //Return status code
   return error;
}
Пример #14
0
error_t rsaesPkcs1v15Decrypt(const RsaPrivateKey *key, const uint8_t *ciphertext,
   size_t ciphertextLength, uint8_t *message, size_t messageSize, size_t *messageLength)
{
   error_t error;
   uint_t i;
   uint_t k;
   uint8_t *em;
   Mpi c;
   Mpi m;

   //Check parameters
   if(key == NULL || ciphertext == NULL)
      return ERROR_INVALID_PARAMETER;
   if(message == NULL || messageLength == NULL)
      return ERROR_INVALID_PARAMETER;

   //Debug message
   TRACE_DEBUG("RSA PKCS #1 v1.5 decryption...\r\n");
   TRACE_DEBUG("  Modulus:\r\n");
   TRACE_DEBUG_MPI("    ", &key->n);
   TRACE_DEBUG("  Public exponent:\r\n");
   TRACE_DEBUG_MPI("    ", &key->e);
   TRACE_DEBUG("  Private exponent:\r\n");
   TRACE_DEBUG_MPI("    ", &key->d);
   TRACE_DEBUG("  Prime 1:\r\n");
   TRACE_DEBUG_MPI("    ", &key->p);
   TRACE_DEBUG("  Prime 2:\r\n");
   TRACE_DEBUG_MPI("    ", &key->q);
   TRACE_DEBUG("  Prime exponent 1:\r\n");
   TRACE_DEBUG_MPI("    ", &key->dp);
   TRACE_DEBUG("  Prime exponent 2:\r\n");
   TRACE_DEBUG_MPI("    ", &key->dq);
   TRACE_DEBUG("  Coefficient:\r\n");
   TRACE_DEBUG_MPI("    ", &key->qinv);
   TRACE_DEBUG("  Ciphertext:\r\n");
   TRACE_DEBUG_ARRAY("    ", ciphertext, ciphertextLength);

   //Initialize multiple-precision integers
   mpiInit(&c);
   mpiInit(&m);

   //Get the length in octets of the modulus n
   k = mpiGetByteLength(&key->n);

   //Check the length of the ciphertext
   if(ciphertextLength != k || ciphertextLength < 11)
      return ERROR_INVALID_LENGTH;

   //Allocate a buffer to store the encoded message EM
   em = osAllocMem(k);
   //Failed to allocate memory?
   if(!em) return ERROR_OUT_OF_MEMORY;

   //Start of exception handling block
   do
   {
      //Convert the ciphertext to an integer ciphertext representative c
      error = mpiReadRaw(&c, ciphertext, ciphertextLength);
      //Conversion failed?
      if(error) break;

      //Apply the RSADP decryption primitive
      error = rsadp(key, &c, &m);
      //Any error to report?
      if(error) break;

      //Convert the message representative m to an encoded message EM of length k octets
      error = mpiWriteRaw(&m, em, k);
      //Conversion failed?
      if(error) break;

      //Debug message
      TRACE_DEBUG("  Encoded message\r\n");
      TRACE_DEBUG_ARRAY("    ", em, k);

      //The first octet of EM must have a value of 0x00
      //and the block type BT shall be 0x02
      if(em[0] != 0x00 || em[1] != 0x02)
      {
         //Report an error
         error = ERROR_UNEXPECTED_VALUE;
         break;
      }

      //An octet with hexadecimal value 0x00 is used to separate PS from M
      for(i = 2; i < k && em[i] != 0x00; i++);

      //Check whether the padding string is valid
      if(i < 10 || i >= k)
      {
         //Report an error
         error = ERROR_INVALID_PADDING;
         break;
      }

      //Ensure that the output buffer is large enough
      if(messageSize < (k - i - 1))
      {
         //Report an error
         error = ERROR_INVALID_LENGTH;
         break;
      }

      //Recover the length of the message
      *messageLength = k - i - 1;
      //Copy the message contents
      memcpy(message, em + i + 1, *messageLength);

      //Debug message
      TRACE_DEBUG("  Message:\r\n");
      TRACE_DEBUG_ARRAY("    ", message, *messageLength);

      //End of exception handling block
   } while(0);

   //Release multiple precision integers
   mpiFree(&c);
   mpiFree(&m);
   //Free previously allocated memory
   osFreeMem(em);

   //Return status code
   return error;
}
Пример #15
0
error_t rsaesPkcs1v15Encrypt(const PrngAlgo *prngAlgo, void *prngContext, const RsaPublicKey *key,
   const uint8_t *message, size_t messageLength, uint8_t *ciphertext, size_t *ciphertextLength)
{
   error_t error;
   uint_t i;
   uint_t j;
   uint_t k;
   uint_t n;
   uint8_t *p;
   Mpi m;
   Mpi c;

   //Check parameters
   if(key == NULL || message == NULL)
      return ERROR_INVALID_PARAMETER;
   if(ciphertext == NULL || ciphertextLength == NULL)
      return ERROR_INVALID_PARAMETER;

   //Debug message
   TRACE_DEBUG("RSA PKCS #1 v1.5 encryption...\r\n");
   TRACE_DEBUG("  Modulus:\r\n");
   TRACE_DEBUG_MPI("    ", &key->n);
   TRACE_DEBUG("  Public exponent:\r\n");
   TRACE_DEBUG_MPI("    ", &key->e);
   TRACE_DEBUG("  Message:\r\n");
   TRACE_DEBUG_ARRAY("    ", message, messageLength);

   //Initialize multiple-precision integers
   mpiInit(&m);
   mpiInit(&c);

   //Get the length in octets of the modulus n
   k = mpiGetByteLength(&key->n);

   //Check the length of the message
   if((messageLength + 11) > k)
      return ERROR_INVALID_LENGTH;

   //Point to the buffer where the encoded message EM will be formatted
   p = ciphertext;

   //The leading 0x00 octet ensures that the encoded message,
   //converted to an integer, is less than the modulus
   *(p++) = 0x00;
   //For a public-key operation, the block type BT shall be 0x02
   *(p++) = 0x02;

   //Length of the padding string PS
   n = k - messageLength - 3;

   //Generate the padding string (pseudo-randomly generated non-zero octets)
   while(n > 0)
   {
      //Generate random data
      error = prngAlgo->read(prngContext, p, n);
      //Any error to report?
      if(error) return error;

      //Parse the resulting octet string
      for(i = 0, j = 0; j < n; j++)
      {
         //Strip any byte with a value of zero
         if(p[j] != 0)
            p[i++] = p[j];
      }

      //Advance data pointer
      p += i;
      n -= i;
   }

   //Append a 0x00 octet to the padding string
   *(p++) = 0x00;
   //Copy the message to be encrypted
   memcpy(p, message, messageLength);

   //Rewind to the beginning of the encoded message
   p = ciphertext;

   //Debug message
   TRACE_DEBUG("  Encoded message\r\n");
   TRACE_DEBUG_ARRAY("    ", p, k);

   //Start of exception handling block
   do
   {
      //Convert the encoded message EM to an integer message representative m
      error = mpiReadRaw(&m, p, k);
      //Conversion failed?
      if(error) break;

      //Apply the RSAEP encryption primitive
      error = rsaep(key, &m, &c);
      //Any error to report?
      if(error) break;

      //Convert the ciphertext representative c to a ciphertext of length k octets
      error = mpiWriteRaw(&c, ciphertext, k);
      //Conversion failed?
      if(error) break;

      //Length of the resulting ciphertext
      *ciphertextLength = k;

      //Debug message
      TRACE_DEBUG("  Ciphertext:\r\n");
      TRACE_DEBUG_ARRAY("    ", ciphertext, *ciphertextLength);

      //End of exception handling block
   } while(0);

   //Free previously allocated memory
   mpiFree(&m);
   mpiFree(&c);

   //Return status code
   return error;
}
Пример #16
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;
}
Пример #17
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;
}
Пример #18
0
error_t ecDouble(const EcDomainParameters *params, EcPoint *r, const EcPoint *s)
{
   error_t error;
   Mpi t1;
   Mpi t2;
   Mpi t3;
   Mpi t4;
   Mpi t5;

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

   //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));

   //Point at the infinity?
   if(!mpiCompInt(&t3, 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
   {
      //SECP K1 elliptic curve?
      if(params->type == EC_CURVE_TYPE_SECP_K1)
      {
         //Compute t5 = t1^2
         EC_CHECK(ecSqrMod(params, &t5, &t1));
         //Compute t4 = 3 * t5
         EC_CHECK(ecAddMod(params, &t4, &t5, &t5));
         EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
      }
      //SECP R1 elliptic curve?
      else if(params->type == EC_CURVE_TYPE_SECP_R1)
      {
         //Compute t4 = t3^2
         EC_CHECK(ecSqrMod(params, &t4, &t3));
         //Compute t5 = t1 - t4
         EC_CHECK(ecSubMod(params, &t5, &t1, &t4));
         //Compute t4 = t1 + t4
         EC_CHECK(ecAddMod(params, &t4, &t1, &t4));
         //Compute t5 = t4 * t5
         EC_CHECK(ecMulMod(params, &t5, &t4, &t5));
         //Compute t4 = 3 * t5
         EC_CHECK(ecAddMod(params, &t4, &t5, &t5));
         EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
      }
      else
      {
         //Compute t4 = t3^4
         EC_CHECK(ecSqrMod(params, &t4, &t3));
         EC_CHECK(ecSqrMod(params, &t4, &t4));
         //Compute t4 = a * t4
         EC_CHECK(ecMulMod(params, &t4, &t4, &params->a));
         //Compute t5 = t1^2
         EC_CHECK(ecSqrMod(params, &t5, &t1));
         //Compute t4 = t4 + 3 * t5
         EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
         EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
         EC_CHECK(ecAddMod(params, &t4, &t4, &t5));
      }

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

      //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);

   //Return status code
   return error;
}