CryptX

 view release on metacpan or  search on metacpan

src/ltc/math/fp/ltc_ecc_fp_mulmod.c  view on Meta::CPAN

    *
    */
   /*
    * The cache itself is a point (3 INTEGERS),
    * the LUT as pairs of INTEGERS (2 * 1<<FP_LUT),
    * and the mu INTEGER
    */
   cache_entry = XCALLOC(FP_ENTRIES*(2*(1U<<FP_LUT)+4)+3, sizeof(ltc_asn1_list));
   if (cache_entry == NULL) {
      LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
      return CRYPT_MEM;
   }
   j = 1;   /* handle the zero'th element later */

   LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1);
   LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1);

   for (i = 0; i < FP_ENTRIES; i++) {
      /*
       * do not save empty entries, or entries that have not yet had the lut built
       */
      if (fp_cache[i].g == NULL || fp_cache[i].lru_count < 2) {
         continue;
      }
      num_entries++;
      LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1);
      LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1);
      LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1);
      for (k = 0; k < (1U<<FP_LUT); k++) {
         LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->x, 1);
         LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->y, 1);
      }
      LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1);
   }
   LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_EOL, 0, 0);

   LTC_SET_ASN1(cache_entry, 0, LTC_ASN1_SHORT_INTEGER, &num_entries, 1);

   if ((err = der_length_sequence(cache_entry, j, outlen)) != CRYPT_OK) {
      goto save_err;
   }
   if ((*out = XMALLOC(*outlen)) == NULL) {
      err = CRYPT_MEM;
      goto save_err;
   }
   err = der_encode_sequence(cache_entry, j, *out, outlen);
save_err:
   XFREE(cache_entry);
   LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
   return err;
}

/** Import a binary packet into the current cache
    @param in      [in] pointer to packet
    @param inlen   [in] size of packet (bytes)
    @return CRYPT_OK if successful
*/
int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen)
{
   int            err;
   ltc_asn1_list *decoded_list, *cur;
   unsigned long  num_entries, fp_entries, fp_lut;
   unsigned long  i, decoded_len;
   unsigned int   x;

   LTC_ARGCHK(in != NULL);
   if (inlen == 0) {
      return CRYPT_INVALID_ARG;
   }

   decoded_list = NULL;
   cur = NULL;
   decoded_len = inlen;

   LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
   /*
    * start with an empty cache
    */
   s_ltc_ecc_fp_free_cache();

   if ((err = der_decode_sequence_flexi(in, &decoded_len, &decoded_list)) != CRYPT_OK) {
      goto ERR_OUT;
   }
   if (decoded_len != inlen) {
      err = CRYPT_INVALID_PACKET;
      goto ERR_OUT;
   }

   cur = decoded_list;
   if (cur == NULL || cur->type != LTC_ASN1_SEQUENCE || cur->child == NULL || cur->next != NULL) {
      err = CRYPT_INVALID_PACKET;
      goto ERR_OUT;
   }

   cur = cur->child;
   if (cur->type != LTC_ASN1_INTEGER) {
      err = CRYPT_INVALID_PACKET;
      goto ERR_OUT;
   }
   num_entries = ltc_mp_get_int(cur->data);
   cur = cur->next;

   if (cur == NULL || cur->type != LTC_ASN1_INTEGER) {
      err = CRYPT_INVALID_PACKET;
      goto ERR_OUT;
   }
   fp_entries = ltc_mp_get_int(cur->data);
   cur = cur->next;

   if (cur == NULL || cur->type != LTC_ASN1_INTEGER) {
      err = CRYPT_INVALID_PACKET;
      goto ERR_OUT;
   }
   fp_lut = ltc_mp_get_int(cur->data);
   cur = cur->next;

   if (fp_entries != FP_ENTRIES || fp_lut != FP_LUT || num_entries > fp_entries) {
      err = CRYPT_INVALID_PACKET;
      goto ERR_OUT;
   }

   for (i = 0; i < num_entries; i++) {
      if((fp_cache[i].g = ltc_ecc_new_point()) == NULL) {
         err = CRYPT_MEM;
         goto ERR_OUT;
      }

      if (cur == NULL || cur->type != LTC_ASN1_INTEGER || (err = ltc_mp_copy(cur->data, fp_cache[i].g->x)) != CRYPT_OK) {
         if (err == CRYPT_OK) err = CRYPT_INVALID_PACKET;
         goto ERR_OUT;
      }
      cur = cur->next;
      if (cur == NULL || cur->type != LTC_ASN1_INTEGER || (err = ltc_mp_copy(cur->data, fp_cache[i].g->y)) != CRYPT_OK) {
         if (err == CRYPT_OK) err = CRYPT_INVALID_PACKET;
         goto ERR_OUT;
      }
      cur = cur->next;
      if (cur == NULL || cur->type != LTC_ASN1_INTEGER || (err = ltc_mp_copy(cur->data, fp_cache[i].g->z)) != CRYPT_OK) {
         if (err == CRYPT_OK) err = CRYPT_INVALID_PACKET;
         goto ERR_OUT;
      }
      cur = cur->next;

      for (x = 0; x < (1U<<FP_LUT); x++) {
         /* since we don't store z in the cache, don't use ltc_ecc_new_point()
          * (which allocates space for z, only to have to free it later) */
         ecc_point *p = XCALLOC(1, sizeof(*p));

         if (p == NULL) {
            err = CRYPT_MEM;
            goto ERR_OUT;
         }
         fp_cache[i].LUT[x] = p;
         if ((err = ltc_mp_init_multi(&p->x, &p->y, LTC_NULL)) != CRYPT_OK) {
            goto ERR_OUT;
         }
         p->z = NULL;

         if (cur == NULL || cur->type != LTC_ASN1_INTEGER || (err = ltc_mp_copy(cur->data, p->x)) != CRYPT_OK) {
            if (err == CRYPT_OK) err = CRYPT_INVALID_PACKET;
            goto ERR_OUT;
         }
         cur = cur->next;
         if (cur == NULL || cur->type != LTC_ASN1_INTEGER || (err = ltc_mp_copy(cur->data, p->y)) != CRYPT_OK) {
            if (err == CRYPT_OK) err = CRYPT_INVALID_PACKET;
            goto ERR_OUT;
         }
         cur = cur->next;
      }

      if (cur == NULL || cur->type != LTC_ASN1_INTEGER) {
         err = CRYPT_INVALID_PACKET;
         goto ERR_OUT;
      }
      if((err = ltc_mp_init_copy(&fp_cache[i].mu, cur->data)) != CRYPT_OK) {
         goto ERR_OUT;
      }
      cur = cur->next;
      fp_cache[i].lru_count = 3;
      fp_cache[i].lock = 1;
   }

    if (cur != NULL) {
      err = CRYPT_INVALID_PACKET;
      goto ERR_OUT;
   }
   der_sequence_free(decoded_list);
   LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
   return CRYPT_OK;
ERR_OUT:
   if (decoded_list != NULL) {
      der_sequence_free(decoded_list);
   }
   s_ltc_ecc_fp_free_cache();
   LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
   return err;
}

#endif



( run in 0.785 second using v1.01-cache-2.11-cpan-0d23b851a93 )