comparison libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c @ 1435:f849a5ca2efc

update to libtomcrypt 1.17 (with Dropbear changes)
author Matt Johnston <matt@ucc.asn.au>
date Sat, 24 Jun 2017 17:50:50 +0800
parents 0cbe8f6dbf9e
children 6dba84798cd5
comparison
equal deleted inserted replaced
1434:27b9ddb06b09 1435:f849a5ca2efc
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 * 8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.com 9 * Tom St Denis, [email protected], http://libtom.org
10 */ 10 */
11 #include "tomcrypt.h" 11 #include "tomcrypt.h"
12 12
13 /** 13 /**
14 @file ltc_ecc_fp_mulmod.c 14 @file ltc_ecc_fp_mulmod.c
15 ECC Crypto, Tom St Denis 15 ECC Crypto, Tom St Denis
16 */ 16 */
17 17
18 #if defined(MECC) && defined(MECC_FP) 18 #if defined(LTC_MECC) && defined(LTC_MECC_FP)
19 #include <limits.h> 19 #include <limits.h>
20 20
21 /* number of entries in the cache */ 21 /* number of entries in the cache */
22 #ifndef FP_ENTRIES 22 #ifndef FP_ENTRIES
23 #define FP_ENTRIES 16 23 #define FP_ENTRIES 16
36 static struct { 36 static struct {
37 ecc_point *g, /* cached COPY of base point */ 37 ecc_point *g, /* cached COPY of base point */
38 *LUT[1U<<FP_LUT]; /* fixed point lookup */ 38 *LUT[1U<<FP_LUT]; /* fixed point lookup */
39 void *mu; /* copy of the montgomery constant */ 39 void *mu; /* copy of the montgomery constant */
40 int lru_count; /* amount of times this entry has been used */ 40 int lru_count; /* amount of times this entry has been used */
41 int lock; /* flag to indicate cache eviction permitted (0) or not (1) */
41 } fp_cache[FP_ENTRIES]; 42 } fp_cache[FP_ENTRIES];
42 43
43 LTC_MUTEX_GLOBAL(ltc_ecc_fp_lock) 44 LTC_MUTEX_GLOBAL(ltc_ecc_fp_lock)
44 45
45 /* simple table to help direct the generation of the LUT */ 46 /* simple table to help direct the generation of the LUT */
570 #endif 571 #endif
571 #endif 572 #endif
572 #endif 573 #endif
573 }; 574 };
574 575
575 /* find a hole and free as required */ 576 /* find a hole and free as required, return -1 if no hole found */
576 static int find_hole(void) 577 static int find_hole(void)
577 { 578 {
578 unsigned x; 579 unsigned x;
579 int y, z; 580 int y, z;
580 for (z = 0, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { 581 for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) {
581 if (fp_cache[x].lru_count < y) { 582 if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) {
582 z = x; 583 z = x;
583 y = fp_cache[x].lru_count; 584 y = fp_cache[x].lru_count;
584 } 585 }
585 } 586 }
586 587
590 --(fp_cache[x].lru_count); 591 --(fp_cache[x].lru_count);
591 } 592 }
592 } 593 }
593 594
594 /* free entry z */ 595 /* free entry z */
595 if (fp_cache[z].g) { 596 if (z >= 0 && fp_cache[z].g) {
596 if (fp_cache[z].mu != NULL) { 597 if (fp_cache[z].mu != NULL) {
597 mp_clear(fp_cache[z].mu); 598 mp_clear(fp_cache[z].mu);
598 fp_cache[z].mu = NULL; 599 fp_cache[z].mu = NULL;
599 } 600 }
600 ltc_ecc_del_point(fp_cache[z].g); 601 ltc_ecc_del_point(fp_cache[z].g);
1098 zeromem(kb, sizeof(kb)); 1099 zeromem(kb, sizeof(kb));
1099 return ltc_ecc_map(R, modulus, mp); 1100 return ltc_ecc_map(R, modulus, mp);
1100 } 1101 }
1101 1102
1102 /** ECC Fixed Point mulmod global 1103 /** ECC Fixed Point mulmod global
1103 @param k The multiplicand 1104 Computes kA*A + kB*B = C using Shamir's Trick
1104 @param G Base point to multiply 1105 @param A First point to multiply
1105 @param R [out] Destination of product 1106 @param kA What to multiple A by
1106 @param modulus The modulus for the curve 1107 @param B Second point to multiply
1107 @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form 1108 @param kB What to multiple B by
1108 @return CRYPT_OK if successful 1109 @param C [out] Destination point (can overlap with A or B)
1109 */ 1110 @param modulus Modulus for curve
1111 @return CRYPT_OK on success
1112 */
1110 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, 1113 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
1111 ecc_point *B, void *kB, 1114 ecc_point *B, void *kB,
1112 ecc_point *C, void *modulus) 1115 ecc_point *C, void *modulus)
1113 { 1116 {
1114 int idx1, idx2, err; 1117 int idx1, idx2, err;
1121 idx1 = find_base(A); 1124 idx1 = find_base(A);
1122 1125
1123 /* no entry? */ 1126 /* no entry? */
1124 if (idx1 == -1) { 1127 if (idx1 == -1) {
1125 /* find hole and add it */ 1128 /* find hole and add it */
1126 idx1 = find_hole(); 1129 if ((idx1 = find_hole()) >= 0) {
1127 1130 if ((err = add_entry(idx1, A)) != CRYPT_OK) {
1128 if ((err = add_entry(idx1, A)) != CRYPT_OK) { 1131 goto LBL_ERR;
1129 goto LBL_ERR; 1132 }
1130 } 1133 }
1131 } 1134 }
1132 1135 if (idx1 != -1) {
1133 /* increment LRU */ 1136 /* increment LRU */
1134 ++(fp_cache[idx1].lru_count); 1137 ++(fp_cache[idx1].lru_count);
1135 1138 }
1139
1136 /* find point */ 1140 /* find point */
1137 idx2 = find_base(B); 1141 idx2 = find_base(B);
1138 1142
1139 /* no entry? */ 1143 /* no entry? */
1140 if (idx2 == -1) { 1144 if (idx2 == -1) {
1141 /* find hole and add it */ 1145 /* find hole and add it */
1142 idx2 = find_hole(); 1146 if ((idx2 = find_hole()) >= 0) {
1143 1147 if ((err = add_entry(idx2, B)) != CRYPT_OK) {
1144 if ((err = add_entry(idx2, B)) != CRYPT_OK) { 1148 goto LBL_ERR;
1145 goto LBL_ERR; 1149 }
1146 } 1150 }
1147 } 1151 }
1148 1152 if (idx2 != -1) {
1149 /* increment LRU */ 1153 /* increment LRU */
1150 ++(fp_cache[idx2].lru_count); 1154 ++(fp_cache[idx2].lru_count);
1155 }
1151 1156
1152 /* if it's 2 build the LUT, if it's higher just use the LUT */ 1157 /* if it's 2 build the LUT, if it's higher just use the LUT */
1153 if (fp_cache[idx1].lru_count == 2) { 1158 if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) {
1154 /* compute mp */ 1159 /* compute mp */
1155 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } 1160 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1156 1161
1157 /* compute mu */ 1162 /* compute mu */
1158 if ((err = mp_init(&mu)) != CRYPT_OK) { 1163 if ((err = mp_init(&mu)) != CRYPT_OK) {
1167 goto LBL_ERR;; 1172 goto LBL_ERR;;
1168 } 1173 }
1169 } 1174 }
1170 1175
1171 /* if it's 2 build the LUT, if it's higher just use the LUT */ 1176 /* if it's 2 build the LUT, if it's higher just use the LUT */
1172 if (fp_cache[idx2].lru_count == 2) { 1177 if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) {
1173 if (mp == NULL) { 1178 if (mp == NULL) {
1174 /* compute mp */ 1179 /* compute mp */
1175 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } 1180 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1176 1181
1177 /* compute mu */ 1182 /* compute mu */
1188 goto LBL_ERR;; 1193 goto LBL_ERR;;
1189 } 1194 }
1190 } 1195 }
1191 1196
1192 1197
1193 if (fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) { 1198 if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) {
1194 if (mp == NULL) { 1199 if (mp == NULL) {
1195 /* compute mp */ 1200 /* compute mp */
1196 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } 1201 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1197 } 1202 }
1198 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp); 1203 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp);
1233 /* no entry? */ 1238 /* no entry? */
1234 if (idx == -1) { 1239 if (idx == -1) {
1235 /* find hole and add it */ 1240 /* find hole and add it */
1236 idx = find_hole(); 1241 idx = find_hole();
1237 1242
1238 if ((err = add_entry(idx, G)) != CRYPT_OK) { 1243 if (idx >= 0) {
1239 goto LBL_ERR; 1244 if ((err = add_entry(idx, G)) != CRYPT_OK) {
1240 } 1245 goto LBL_ERR;
1241 } 1246 }
1242 1247 }
1243 /* increment LRU */ 1248 }
1244 ++(fp_cache[idx].lru_count); 1249 if (idx != -1) {
1250 /* increment LRU */
1251 ++(fp_cache[idx].lru_count);
1252 }
1253
1245 1254
1246 /* if it's 2 build the LUT, if it's higher just use the LUT */ 1255 /* if it's 2 build the LUT, if it's higher just use the LUT */
1247 if (fp_cache[idx].lru_count == 2) { 1256 if (idx >= 0 && fp_cache[idx].lru_count == 2) {
1248 /* compute mp */ 1257 /* compute mp */
1249 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } 1258 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1250 1259
1251 /* compute mu */ 1260 /* compute mu */
1252 if ((err = mp_init(&mu)) != CRYPT_OK) { 1261 if ((err = mp_init(&mu)) != CRYPT_OK) {
1260 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { 1269 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1261 goto LBL_ERR;; 1270 goto LBL_ERR;;
1262 } 1271 }
1263 } 1272 }
1264 1273
1265 if (fp_cache[idx].lru_count >= 2) { 1274 if (idx >= 0 && fp_cache[idx].lru_count >= 2) {
1266 if (mp == NULL) { 1275 if (mp == NULL) {
1267 /* compute mp */ 1276 /* compute mp */
1268 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } 1277 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
1269 } 1278 }
1270 err = accel_fp_mul(idx, k, R, modulus, mp, map); 1279 err = accel_fp_mul(idx, k, R, modulus, mp, map);
1280 mp_clear(mu); 1289 mp_clear(mu);
1281 } 1290 }
1282 return err; 1291 return err;
1283 } 1292 }
1284 1293
1285 /** Free the Fixed Point tables */ 1294 /* helper function for freeing the cache ... must be called with the cache mutex locked */
1286 void ltc_ecc_fp_free(void) 1295 static void ltc_ecc_fp_free_cache(void)
1287 { 1296 {
1288 unsigned x, y; 1297 unsigned x, y;
1289 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1290 for (x = 0; x < FP_ENTRIES; x++) { 1298 for (x = 0; x < FP_ENTRIES; x++) {
1291 if (fp_cache[x].g != NULL) { 1299 if (fp_cache[x].g != NULL) {
1292 for (y = 0; y < (1U<<FP_LUT); y++) { 1300 for (y = 0; y < (1U<<FP_LUT); y++) {
1293 ltc_ecc_del_point(fp_cache[x].LUT[y]); 1301 ltc_ecc_del_point(fp_cache[x].LUT[y]);
1294 fp_cache[x].LUT[y] = NULL; 1302 fp_cache[x].LUT[y] = NULL;
1298 if (fp_cache[x].mu != NULL) { 1306 if (fp_cache[x].mu != NULL) {
1299 mp_clear(fp_cache[x].mu); 1307 mp_clear(fp_cache[x].mu);
1300 fp_cache[x].mu = NULL; 1308 fp_cache[x].mu = NULL;
1301 } 1309 }
1302 fp_cache[x].lru_count = 0; 1310 fp_cache[x].lru_count = 0;
1311 fp_cache[x].lock = 0;
1303 } 1312 }
1304 } 1313 }
1314 }
1315
1316 /** Free the Fixed Point cache */
1317 void ltc_ecc_fp_free(void)
1318 {
1319 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1320 ltc_ecc_fp_free_cache();
1305 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock); 1321 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1306 } 1322 }
1323
1324 /** Add a point to the cache and initialize the LUT
1325 @param g The point to add
1326 @param modulus Modulus for curve
1327 @param lock Flag to indicate if this entry should be locked into the cache or not
1328 @return CRYPT_OK on success
1329 */
1330 int
1331 ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock)
1332 {
1333 int idx;
1334 int err;
1335 void *mp = NULL;
1336 void *mu = NULL;
1337
1338 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1339 if ((idx = find_base(g)) >= 0) {
1340 /* it is already in the cache ... just check that the LUT is initialized */
1341 if(fp_cache[idx].lru_count >= 2) {
1342 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1343 return CRYPT_OK;
1344 }
1345 }
1346
1347 if(idx == -1 && (idx = find_hole()) == -1) {
1348 err = CRYPT_BUFFER_OVERFLOW;
1349 goto LBL_ERR;
1350 }
1351 if ((err = add_entry(idx, g)) != CRYPT_OK) {
1352 goto LBL_ERR;
1353 }
1354 /* compute mp */
1355 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) {
1356 goto LBL_ERR;
1357 }
1358
1359 /* compute mu */
1360 if ((err = mp_init(&mu)) != CRYPT_OK) {
1361 goto LBL_ERR;
1362 }
1363 if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) {
1364 goto LBL_ERR;
1365 }
1366
1367 /* build the LUT */
1368 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1369 goto LBL_ERR;
1370 }
1371 fp_cache[idx].lru_count = 2;
1372 fp_cache[idx].lock = lock;
1373 LBL_ERR:
1374 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1375 if (mp != NULL) {
1376 mp_montgomery_free(mp);
1377 }
1378 if (mu != NULL) {
1379 mp_clear(mu);
1380 }
1381 return err;
1382 }
1383
1384 /** Prevent/permit the FP cache from being updated
1385 @param flag If flag is 0, remove cache lock (unlock), otherwise lock it
1386 */
1387 void ltc_ecc_fp_tablelock(int lock)
1388 {
1389 int i;
1390
1391 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1392 for (i = 0; i < FP_ENTRIES; i++) {
1393 fp_cache[i].lock = lock;
1394 }
1395 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1396 }
1397
1398 /** Export the current cache as a binary packet
1399 @param out [out] pointer to malloc'ed space containing the packet
1400 @param outlen [out] size of exported packet
1401 @return CRYPT_OK if successful
1402 */
1403 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen)
1404 {
1405 ltc_asn1_list *cache_entry;
1406 unsigned int i, j, k;
1407 unsigned long fp_entries, fp_lut, num_entries;
1408 int err;
1409
1410 LTC_ARGCHK(out != NULL);
1411 LTC_ARGCHK(outlen != NULL);
1412
1413 fp_entries = FP_ENTRIES;
1414 fp_lut = FP_LUT;
1415 num_entries = 0;
1416
1417 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1418 /*
1419 * build the list;
1420 Cache DEFINITIONS ::=
1421 BEGIN
1422 CacheDump ::= SEQUENCE {
1423 numEntries SHORTINTEGER,
1424 maxEntries SHORTINTEGER,
1425 numLUT SHORTINTEGER,
1426 cache SEQUENCE OF INTEGER
1427 }
1428 END
1429 *
1430 */
1431 /*
1432 * The cache itself is a point (3 INTEGERS),
1433 * the LUT as pairs of INTEGERS (2 * 1<<FP_LUT),
1434 * and the mu INTEGER
1435 */
1436 cache_entry = XCALLOC(FP_ENTRIES*(2*(1U<<FP_LUT)+4)+3, sizeof(ltc_asn1_list));
1437 if (cache_entry == NULL)
1438 return CRYPT_MEM;
1439 j = 1; /* handle the zero'th element later */
1440
1441 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1);
1442 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1);
1443
1444 for (i = 0; i < FP_ENTRIES; i++) {
1445 /*
1446 * do not save empty entries, or entries that have not yet had the lut built
1447 */
1448 if (fp_cache[i].g == NULL || fp_cache[i].lru_count < 2) {
1449 continue;
1450 }
1451 num_entries++;
1452 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1);
1453 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1);
1454 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1);
1455 for (k = 0; k < (1U<<FP_LUT); k++) {
1456 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->x, 1);
1457 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->y, 1);
1458 }
1459 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1);
1460 }
1461 LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_EOL, 0, 0);
1462
1463 LTC_SET_ASN1(cache_entry, 0, LTC_ASN1_SHORT_INTEGER, &num_entries, 1);
1464
1465 if ((err = der_length_sequence(cache_entry, j, outlen)) != CRYPT_OK) {
1466 goto save_err;
1467 }
1468 if ((*out = XMALLOC(*outlen)) == NULL) {
1469 err = CRYPT_MEM;
1470 goto save_err;
1471 }
1472 err = der_encode_sequence(cache_entry, j, *out, outlen);
1473 save_err:
1474 XFREE(cache_entry);
1475 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1476 return err;
1477 }
1478
1479 /** Import a binary packet into the current cache
1480 @param in [in] pointer to packet
1481 @param inlen [in] size of packet (bytes)
1482 @return CRYPT_OK if successful
1483 */
1484 int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen)
1485 {
1486 int err;
1487 ltc_asn1_list *asn1_list;
1488 unsigned long num_entries, fp_entries, fp_lut;
1489 unsigned long i, j;
1490 unsigned int x;
1491
1492 LTC_ARGCHK(in != NULL);
1493 if (inlen == 0) {
1494 return CRYPT_INVALID_ARG;
1495 }
1496
1497 /* zero indecies */
1498 i = 0;
1499 j = 0;
1500 asn1_list = NULL;
1501
1502 LTC_MUTEX_LOCK(&ltc_ecc_fp_lock);
1503 /*
1504 * start with an empty cache
1505 */
1506 ltc_ecc_fp_free_cache();
1507
1508 /*
1509 * decode the input packet: It consists of a sequence with a few
1510 * integers (including the FP_ENTRIES and FP_LUT sizes), followed by a
1511 * SEQUENCE which is the cache itself.
1512 *
1513 * use standard decoding for the first part, then flexible for the second
1514 */
1515 if((err = der_decode_sequence_multi(in, inlen,
1516 LTC_ASN1_SHORT_INTEGER, 1, &num_entries,
1517 LTC_ASN1_SHORT_INTEGER, 1, &fp_entries,
1518 LTC_ASN1_SHORT_INTEGER, 1, &fp_lut,
1519 LTC_ASN1_EOL, 0, 0)) != CRYPT_OK) {
1520 goto ERR_OUT;
1521 }
1522 if (fp_entries != FP_ENTRIES || fp_lut != FP_LUT || num_entries > fp_entries) {
1523 err = CRYPT_INVALID_PACKET;
1524 goto ERR_OUT;
1525 }
1526 if ((asn1_list = XCALLOC(3+num_entries*(4+2*(1<<FP_LUT))+1, sizeof(ltc_asn1_list))) == NULL) {
1527 err = CRYPT_MEM;
1528 goto ERR_OUT;
1529 }
1530 j = 0;
1531 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &num_entries, 1);
1532 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &fp_entries, 1);
1533 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_SHORT_INTEGER, &fp_lut, 1);
1534 for (i = 0; i < num_entries; i++) {
1535 if((fp_cache[i].g = ltc_ecc_new_point()) == NULL) {
1536 err = CRYPT_MEM;
1537 goto ERR_OUT;
1538 }
1539 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->x, 1);
1540 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1);
1541 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1);
1542 for (x = 0; x < (1U<<FP_LUT); x++) {
1543 /* since we don't store z in the cache, don't use ltc_ecc_new_point()
1544 * (which allocates space for z, only to have to free it later) */
1545 ecc_point *p = XCALLOC(1, sizeof(*p));
1546
1547 if (p == NULL) {
1548 err = CRYPT_MEM;
1549 goto ERR_OUT;
1550 }
1551 fp_cache[i].LUT[x] = p;
1552 if ((err = mp_init_multi(&p->x, &p->y, NULL)) != CRYPT_OK) {
1553 goto ERR_OUT;
1554 }
1555 p->z = NULL;
1556 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->x, 1);
1557 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->y, 1);
1558 }
1559 if((err = mp_init(&fp_cache[i].mu)) != CRYPT_OK) {
1560 goto ERR_OUT;
1561 }
1562 LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1);
1563 fp_cache[i].lru_count = 3;
1564 fp_cache[i].lock = 1;
1565 }
1566
1567 if ((err = der_decode_sequence(in, inlen, asn1_list, j)) != CRYPT_OK) {
1568 goto ERR_OUT;
1569 }
1570 XFREE(asn1_list);
1571 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1572 return CRYPT_OK;
1573 ERR_OUT:
1574 if(asn1_list)
1575 XFREE(asn1_list);
1576 ltc_ecc_fp_free_cache();
1577 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
1578 return err;
1579 }
1307 1580
1308 #endif 1581 #endif
1309 1582
1310 1583
1311 /* $Source: /cvs/libtom/libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c,v $ */ 1584 /* $Source$ */
1312 /* $Revision: 1.27 $ */ 1585 /* $Revision$ */
1313 /* $Date: 2006/12/03 00:39:56 $ */ 1586 /* $Date$ */
1314 1587