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(<c_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(<c_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(<c_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(<c_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(<c_ecc_fp_lock);
return err;
}
#endif
( run in 0.785 second using v1.01-cache-2.11-cpan-0d23b851a93 )