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(<c_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(<c_ecc_fp_lock);
s_ltc_ecc_fp_free_cache();
LTC_MUTEX_UNLOCK(<c_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(<c_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(<c_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(<c_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 )