CryptX

 view release on metacpan or  search on metacpan

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


         /* match ltc_ecc_mulmod(): keep ma == NULL for curves with a == -3 */
         if ((err = ltc_mp_init(&a_plus3)) != CRYPT_OK) {
            goto LBL_ERR;
         }
         if ((err = ltc_mp_add_d(a, 3, a_plus3)) != CRYPT_OK) {
            goto LBL_ERR;
         }
         if (ltc_mp_cmp(a_plus3, modulus) != LTC_MP_EQ) {
            if ((err = ltc_mp_init(&ma)) != CRYPT_OK) {
               goto LBL_ERR;
            }
            if ((err = ltc_mp_init(&mu)) != CRYPT_OK) {
               goto LBL_ERR;
            }
            if ((err = ltc_mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
               goto LBL_ERR;
            }
            if ((err = ltc_mp_mulmod(a, mu, modulus, ma)) != CRYPT_OK) {
               goto LBL_ERR;
            }
         } else if (fp_cache[idx].lru_count == 2) {
            if ((err = ltc_mp_init(&mu)) != CRYPT_OK) {
               goto LBL_ERR;
            }
            if ((err = ltc_mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
               goto LBL_ERR;
            }
         }

         /* if it's 2 build the LUT, if it's higher just use the LUT */
         if (fp_cache[idx].lru_count == 2) {
            if ((err = s_build_lut(idx, ma, modulus, mp, mu)) != CRYPT_OK) {
               goto LBL_ERR;
            }
         }
      }

      if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
         err = s_accel_fp_mul(idx, k, R, ma, modulus, mp, map);
      } else {
         err = ltc_ecc_mulmod(k, G, R, a, modulus, map);
      }
LBL_ERR:
    LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
    if (mp != NULL) {
       ltc_mp_montgomery_free(mp);
    }
    if (mu != NULL) {
       ltc_mp_clear(mu);
    }
    if (ma != NULL) {
       ltc_mp_clear(ma);
    }
    if (a_plus3 != NULL) {
       ltc_mp_clear(a_plus3);
    }
    return err;
}

/* helper function for freeing the cache ... must be called with the cache mutex locked */
static void s_ltc_ecc_fp_free_cache(void)
{
   unsigned x, y;
   for (x = 0; x < FP_ENTRIES; x++) {
      if (fp_cache[x].g != NULL) {
         for (y = 0; y < (1U<<FP_LUT); y++) {
            ltc_ecc_del_point(fp_cache[x].LUT[y]);
            fp_cache[x].LUT[y] = NULL;
         }
         ltc_ecc_del_point(fp_cache[x].g);
         fp_cache[x].g         = NULL;
         if (fp_cache[x].mu != NULL) {
            ltc_mp_clear(fp_cache[x].mu);
            fp_cache[x].mu     = NULL;
         }
         fp_cache[x].lru_count = 0;
         fp_cache[x].lock = 0;
      }
   }
}

/** Free the Fixed Point cache */
int ltc_ecc_fp_free(void)
{
   LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
   s_ltc_ecc_fp_free_cache();
   LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
   return CRYPT_OK;
}

/** Add a point to the cache and initialize the LUT
  @param g        The point to add
  @param modulus  Modulus for curve
  @param lock     Flag to indicate if this entry should be locked into the cache or not
  @return CRYPT_OK on success
*/
int
ltc_ecc_fp_add_point(const ecc_point *g, const void *ma, const void *modulus, int lock)
{
   int idx;
   int err;
   void *mp = NULL;
   void *mu = NULL;

   LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
   if ((idx = s_find_base(g)) >= 0) {
      /* it is already in the cache ... just check that the LUT is initialized */
      if(fp_cache[idx].lru_count >= 2) {
         LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
         return CRYPT_OK;
      }
   }

   if (idx == -1 && (idx = s_find_hole()) == -1) {
      err = CRYPT_BUFFER_OVERFLOW;
      goto LBL_ERR;
   }

   if (idx >= 0 && fp_cache[idx].g == NULL) {
      if ((err = s_add_entry(idx, g)) != CRYPT_OK) {
         goto LBL_ERR;
      }
   }

   /* compute mp */
   if ((err = ltc_mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   /* compute mu */
   if ((err = ltc_mp_init(&mu)) != CRYPT_OK) {
      goto LBL_ERR;
   }
   if ((err = ltc_mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
      goto LBL_ERR;
   }

   if ((err = s_build_lut(idx, ma, modulus, mp, mu)) != CRYPT_OK) {
      goto LBL_ERR;
   }
   fp_cache[idx].lru_count = 2;
   fp_cache[idx].lock = lock;
LBL_ERR:
   LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
   if (mp != NULL) {
      ltc_mp_montgomery_free(mp);
   }
   if (mu != NULL) {
      ltc_mp_clear(mu);
   }
   return err;
}

/** Prevent/permit the FP cache from being updated



( run in 1.003 second using v1.01-cache-2.11-cpan-354807fb38d )